public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 0/7] Add XThead* support
@ 2022-11-13 21:46 Christoph Muellner
  2022-11-13 21:46 ` [PATCH 1/7] riscv: Add basic XThead* vendor extension support Christoph Muellner
                   ` (6 more replies)
  0 siblings, 7 replies; 20+ messages in thread
From: Christoph Muellner @ 2022-11-13 21:46 UTC (permalink / raw)
  To: gcc-patches, Kito Cheng, Jim Wilson, Palmer Dabbelt,
	Andrew Waterman, Philipp Tomsich, Cooper Qu, Lifang Xia,
	Yunhai Shang, Zhiwei Liu
  Cc: Christoph Müllner

From: Christoph Müllner <christoph.muellner@vrull.eu>

This series adds support for the following vendor extensions
from T-Head:

* XTheadCmo, XTheadSync
* XTheadBa, XTheadBb, XTheadBs
* XTheadCondMov
* XTheadMac
* XTheadFmv, XTheadInt

No regressions observed.

Christoph Müllner (7):
  riscv: Add basic XThead* vendor extension support
  riscv: riscv-cores.def: Add T-Head XuanTie C906
  riscv: thead: Add support for XTheadBa and XTheadBs ISA extensions
  riscv: thead: Add support for XTheadCondMov ISA extensions
  riscv: thead: Add support for XTheadBb ISA extension
  riscv: thead: Add support for XTheadMac ISA extension
  riscv: Add basic extension support for XTheadFmv and XTheadInt

 gcc/common/config/riscv/riscv-common.cc       |  24 ++
 gcc/config/riscv/bitmanip.md                  |  47 +++-
 gcc/config/riscv/iterators.md                 |   4 +
 gcc/config/riscv/riscv-cores.def              |   2 +
 gcc/config/riscv/riscv-opts.h                 |  23 ++
 gcc/config/riscv/riscv.cc                     |  67 ++++-
 gcc/config/riscv/riscv.md                     |  52 +++-
 gcc/config/riscv/riscv.opt                    |   3 +
 gcc/config/riscv/thead.md                     | 252 ++++++++++++++++++
 .../gcc.target/riscv/mcpu-thead-c906.c        |  18 ++
 gcc/testsuite/gcc.target/riscv/thead-mula-1.c |  40 +++
 gcc/testsuite/gcc.target/riscv/thead-mula-2.c |  28 ++
 .../gcc.target/riscv/xtheadba-addsl-64.c      |  18 ++
 .../gcc.target/riscv/xtheadba-addsl.c         |  20 ++
 gcc/testsuite/gcc.target/riscv/xtheadba.c     |  13 +
 gcc/testsuite/gcc.target/riscv/xtheadbb-ext.c |  19 ++
 .../gcc.target/riscv/xtheadbb-extu.c          |  12 +
 gcc/testsuite/gcc.target/riscv/xtheadbb-rev.c |  40 +++
 .../gcc.target/riscv/xtheadbb-srri.c          |  18 ++
 gcc/testsuite/gcc.target/riscv/xtheadbb.c     |  13 +
 gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c |  12 +
 gcc/testsuite/gcc.target/riscv/xtheadbs.c     |  13 +
 gcc/testsuite/gcc.target/riscv/xtheadcmo.c    |  13 +
 .../riscv/xtheadcondmov-mveqz-imm-eqz.c       |  37 +++
 .../riscv/xtheadcondmov-mveqz-imm-not.c       |  37 +++
 .../riscv/xtheadcondmov-mveqz-reg-eqz.c       |  37 +++
 .../riscv/xtheadcondmov-mveqz-reg-not.c       |  37 +++
 .../riscv/xtheadcondmov-mvnez-imm-cond.c      |  37 +++
 .../riscv/xtheadcondmov-mvnez-imm-nez.c       |  37 +++
 .../riscv/xtheadcondmov-mvnez-reg-cond.c      |  37 +++
 .../riscv/xtheadcondmov-mvnez-reg-nez.c       |  37 +++
 .../gcc.target/riscv/xtheadcondmov.c          |  13 +
 .../gcc.target/riscv/xtheadfmemidx.c          |  13 +
 gcc/testsuite/gcc.target/riscv/xtheadfmv.c    |  14 +
 gcc/testsuite/gcc.target/riscv/xtheadint.c    |  14 +
 gcc/testsuite/gcc.target/riscv/xtheadmac.c    |  13 +
 gcc/testsuite/gcc.target/riscv/xtheadmemidx.c |  13 +
 gcc/testsuite/gcc.target/riscv/xtheadsync.c   |  13 +
 38 files changed, 1123 insertions(+), 17 deletions(-)
 create mode 100644 gcc/config/riscv/thead.md
 create mode 100644 gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/thead-mula-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/thead-mula-2.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadba-addsl-64.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadba-addsl.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadba.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-ext.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-extu.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-rev.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-srri.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbs.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcmo.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-eqz.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-not.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-eqz.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-not.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-cond.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-nez.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-reg-cond.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-reg-nez.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmv.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadint.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmac.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmemidx.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadsync.c

-- 
2.38.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 1/7] riscv: Add basic XThead* vendor extension support
  2022-11-13 21:46 [PATCH 0/7] Add XThead* support Christoph Muellner
@ 2022-11-13 21:46 ` Christoph Muellner
  2022-11-13 21:46 ` [PATCH 2/7] riscv: riscv-cores.def: Add T-Head XuanTie C906 Christoph Muellner
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 20+ messages in thread
From: Christoph Muellner @ 2022-11-13 21:46 UTC (permalink / raw)
  To: gcc-patches, Kito Cheng, Jim Wilson, Palmer Dabbelt,
	Andrew Waterman, Philipp Tomsich, Cooper Qu, Lifang Xia,
	Yunhai Shang, Zhiwei Liu
  Cc: Christoph Müllner

From: Christoph Müllner <christoph.muellner@vrull.eu>

This patch add basic support for the following XThead* ISA extensions:

* XTheadCmo, XTheadSync
* XTheadBa, XTheadBb, XTheadBs, XTheadCondMov
* XTheadMac
* XTheadFMemIdx, XTheadMemIdx

gcc/ChangeLog:

	* common/config/riscv/riscv-common.cc: Add xthead* extensions.
	* config/riscv/riscv-opts.h (MASK_XTHEADBA): New.
	(TARGET_XTHEADBA): New.
	(MASK_XTHEADBB): New.
	(TARGET_XTHEADBB): New.
	(MASK_XTHEADBS): New.
	(TARGET_XTHEADBS): New.
	(MASK_XTHEADCMO): New.
	(TARGET_XTHEADCMO): New.
	(MASK_XTHEADCONDMOV): New.
	(TARGET_XTHEADCONDMOV): New.
	(MASK_XTHEADFMEMIDX): New.
	(TARGET_XTHEADFMEMIDX): New.
	(MASK_XTHEADMAC): New.
	(TARGET_XTHEADMAC): New.
	(MASK_XTHEADMEMIDX): New.
	(TARGET_XTHEADMEMIDX): New.
	(MASK_XTHEADSYNC): New.
	(TARGET_XTHEADSYNC): New.
	* config/riscv/riscv.opt: Add riscv_xthead_subext.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/xtheadba.c: New test.
	* gcc.target/riscv/xtheadbb.c: New test.
	* gcc.target/riscv/xtheadbs.c: New test.
	* gcc.target/riscv/xtheadcmo.c: New test.
	* gcc.target/riscv/xtheadcondmov.c: New test.
	* gcc.target/riscv/xtheadfmemidx.c: New test.
	* gcc.target/riscv/xtheadmac.c: New test.
	* gcc.target/riscv/xtheadmemidx.c: New test.
	* gcc.target/riscv/xtheadsync.c: New test.

Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
---
 gcc/common/config/riscv/riscv-common.cc       | 20 +++++++++++++++++++
 gcc/config/riscv/riscv-opts.h                 | 19 ++++++++++++++++++
 gcc/config/riscv/riscv.opt                    |  3 +++
 gcc/testsuite/gcc.target/riscv/xtheadba.c     | 13 ++++++++++++
 gcc/testsuite/gcc.target/riscv/xtheadbb.c     | 13 ++++++++++++
 gcc/testsuite/gcc.target/riscv/xtheadbs.c     | 13 ++++++++++++
 gcc/testsuite/gcc.target/riscv/xtheadcmo.c    | 13 ++++++++++++
 .../gcc.target/riscv/xtheadcondmov.c          | 13 ++++++++++++
 .../gcc.target/riscv/xtheadfmemidx.c          | 13 ++++++++++++
 gcc/testsuite/gcc.target/riscv/xtheadmac.c    | 13 ++++++++++++
 gcc/testsuite/gcc.target/riscv/xtheadmemidx.c | 13 ++++++++++++
 gcc/testsuite/gcc.target/riscv/xtheadsync.c   | 13 ++++++++++++
 12 files changed, 159 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadba.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbs.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcmo.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmemidx.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmac.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadmemidx.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadsync.c

diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc
index 4b7f777c103..8e1449d3543 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -222,6 +222,16 @@ static const struct riscv_ext_version riscv_ext_version_table[] =
   {"svinval", ISA_SPEC_CLASS_NONE, 1, 0},
   {"svnapot", ISA_SPEC_CLASS_NONE, 1, 0},
 
+  {"xtheadba", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadbb", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadbs", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadcmo", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadcondmov", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadfmemidx", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadmac", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadmemidx", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadsync", ISA_SPEC_CLASS_NONE, 1, 0},
+
   /* Terminate the list.  */
   {NULL, ISA_SPEC_CLASS_NONE, 0, 0}
 };
@@ -1247,6 +1257,16 @@ static const riscv_ext_flag_table_t riscv_ext_flag_table[] =
   {"svinval", &gcc_options::x_riscv_sv_subext, MASK_SVINVAL},
   {"svnapot", &gcc_options::x_riscv_sv_subext, MASK_SVNAPOT},
 
+  {"xtheadba",      &gcc_options::x_riscv_xthead_subext, MASK_XTHEADBA},
+  {"xtheadbb",      &gcc_options::x_riscv_xthead_subext, MASK_XTHEADBB},
+  {"xtheadbs",      &gcc_options::x_riscv_xthead_subext, MASK_XTHEADBS},
+  {"xtheadcmo",     &gcc_options::x_riscv_xthead_subext, MASK_XTHEADCMO},
+  {"xtheadcondmov", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADCONDMOV},
+  {"xtheadfmemidx", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADFMEMIDX},
+  {"xtheadmac",     &gcc_options::x_riscv_xthead_subext, MASK_XTHEADMAC},
+  {"xtheadmemidx",  &gcc_options::x_riscv_xthead_subext, MASK_XTHEADMEMIDX},
+  {"xtheadsync",    &gcc_options::x_riscv_xthead_subext, MASK_XTHEADSYNC},
+
   {NULL, NULL, 0}
 };
 
diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
index 25fd85b09b1..18daac40dbd 100644
--- a/gcc/config/riscv/riscv-opts.h
+++ b/gcc/config/riscv/riscv-opts.h
@@ -189,4 +189,23 @@ enum stack_protector_guard {
    ? 0 \
    : 32 << (__builtin_popcount (riscv_zvl_flags) - 1))
 
+#define MASK_XTHEADBA		(1 << 0)
+#define TARGET_XTHEADBA		((riscv_xthead_subext & MASK_XTHEADBA) != 0)
+#define MASK_XTHEADBB		(1 << 1)
+#define TARGET_XTHEADBB		((riscv_xthead_subext & MASK_XTHEADBB) != 0)
+#define MASK_XTHEADBS		(1 << 2)
+#define TARGET_XTHEADBS		((riscv_xthead_subext & MASK_XTHEADBS) != 0)
+#define MASK_XTHEADCMO		(1 << 3)
+#define TARGET_XTHEADCMO	((riscv_xthead_subext & MASK_XTHEADCMO) != 0)
+#define MASK_XTHEADCONDMOV	(1 << 4)
+#define TARGET_XTHEADCONDMOV	((riscv_xthead_subext & MASK_XTHEADCONDMOV) != 0)
+#define MASK_XTHEADFMEMIDX	(1 << 5)
+#define TARGET_XTHEADFMEMIDX	((riscv_xthead_subext & MASK_XTHEADFMEMIDX) != 0)
+#define MASK_XTHEADMAC		(1 << 6)
+#define TARGET_XTHEADMAC	((riscv_xthead_subext & MASK_XTHEADMAC) != 0)
+#define MASK_XTHEADMEMIDX	(1 << 7)
+#define TARGET_XTHEADMEMIDX	((riscv_xthead_subext & MASK_XTHEADMEMIDX) != 0)
+#define MASK_XTHEADSYNC		(1 << 8)
+#define TARGET_XTHEADSYNC	((riscv_xthead_subext & MASK_XTHEADSYNC) != 0)
+
 #endif /* ! GCC_RISCV_OPTS_H */
diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index 7c3ca48d1cc..3f2dd24d59b 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -233,6 +233,9 @@ int riscv_zm_subext
 TargetVariable
 int riscv_sv_subext
 
+TargetVariable
+int riscv_xthead_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/testsuite/gcc.target/riscv/xtheadba.c b/gcc/testsuite/gcc.target/riscv/xtheadba.c
new file mode 100644
index 00000000000..c91b95b94a8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadba.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xtheadba" { target { rv64 } } } */
+
+#ifndef __riscv_xtheadba
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+  return a;
+}
+
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb.c b/gcc/testsuite/gcc.target/riscv/xtheadbb.c
new file mode 100644
index 00000000000..4872faa999d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadbb.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xtheadbb" { target { rv64 } } } */
+
+#ifndef __riscv_xtheadbb
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+  return a;
+}
+
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbs.c b/gcc/testsuite/gcc.target/riscv/xtheadbs.c
new file mode 100644
index 00000000000..9350505ebb1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadbs.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xtheadbs" { target { rv64 } } } */
+
+#ifndef __riscv_xtheadbs
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+  return a;
+}
+
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcmo.c b/gcc/testsuite/gcc.target/riscv/xtheadcmo.c
new file mode 100644
index 00000000000..ce56f9a1277
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadcmo.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xtheadcmo" { target { rv64 } } } */
+
+#ifndef __riscv_xtheadcmo
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+  return a;
+}
+
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov.c b/gcc/testsuite/gcc.target/riscv/xtheadcondmov.c
new file mode 100644
index 00000000000..9324b30f6bd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadcondmov.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xtheadcondmov" { target { rv64 } } } */
+
+#ifndef __riscv_xtheadcondmov
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+  return a;
+}
+
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmemidx.c b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx.c
new file mode 100644
index 00000000000..9e69ee45cad
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadfmemidx.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xtheadfmemidx" { target { rv64 } } } */
+
+#ifndef __riscv_xtheadfmemidx
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+  return a;
+}
+
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmac.c b/gcc/testsuite/gcc.target/riscv/xtheadmac.c
new file mode 100644
index 00000000000..d8f356bbdec
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadmac.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xtheadmac" { target { rv64 } } } */
+
+#ifndef __riscv_xtheadmac
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+  return a;
+}
+
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadmemidx.c b/gcc/testsuite/gcc.target/riscv/xtheadmemidx.c
new file mode 100644
index 00000000000..bd1545c0c24
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadmemidx.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xtheadmemidx" { target { rv64 } } } */
+
+#ifndef __riscv_xtheadmemidx
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+  return a;
+}
+
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadsync.c b/gcc/testsuite/gcc.target/riscv/xtheadsync.c
new file mode 100644
index 00000000000..e51457e5376
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadsync.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xtheadsync" { target { rv64 } } } */
+
+#ifndef __riscv_xtheadsync
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+  return a;
+}
+
-- 
2.38.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 2/7] riscv: riscv-cores.def: Add T-Head XuanTie C906
  2022-11-13 21:46 [PATCH 0/7] Add XThead* support Christoph Muellner
  2022-11-13 21:46 ` [PATCH 1/7] riscv: Add basic XThead* vendor extension support Christoph Muellner
@ 2022-11-13 21:46 ` Christoph Muellner
  2022-11-18  4:50   ` cooper.qu
  2022-11-13 21:46 ` [PATCH 3/7] riscv: thead: Add support for XTheadBa and XTheadBs ISA extensions Christoph Muellner
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 20+ messages in thread
From: Christoph Muellner @ 2022-11-13 21:46 UTC (permalink / raw)
  To: gcc-patches, Kito Cheng, Jim Wilson, Palmer Dabbelt,
	Andrew Waterman, Philipp Tomsich, Cooper Qu, Lifang Xia,
	Yunhai Shang, Zhiwei Liu
  Cc: Christoph Müllner

From: Christoph Müllner <christoph.muellner@vrull.eu>

This adds T-Head's XuanTie C906 to the list of known cores as "thead-c906".
The C906 is shipped for quite some time (it is the core of the Allwinner D1).
Note, that the tuning struct for the C906 is already part of GCC (it is
also name "thead-c906").

gcc/ChangeLog:

	* config/riscv/riscv-cores.def (RISCV_CORE): Add "thead-c906".

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/mcpu-thead-c906.c: New test.

Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
---
 gcc/config/riscv/riscv-cores.def               |  2 ++
 .../gcc.target/riscv/mcpu-thead-c906.c         | 18 ++++++++++++++++++
 2 files changed, 20 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c

diff --git a/gcc/config/riscv/riscv-cores.def b/gcc/config/riscv/riscv-cores.def
index 31ad34682c5..648a010e09b 100644
--- a/gcc/config/riscv/riscv-cores.def
+++ b/gcc/config/riscv/riscv-cores.def
@@ -73,4 +73,6 @@ RISCV_CORE("sifive-s76",      "rv64imafdc", "sifive-7-series")
 RISCV_CORE("sifive-u54",      "rv64imafdc", "sifive-5-series")
 RISCV_CORE("sifive-u74",      "rv64imafdc", "sifive-7-series")
 
+RISCV_CORE("thead-c906",      "rv64imafdc", "thead-c906")
+
 #undef RISCV_CORE
diff --git a/gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c b/gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c
new file mode 100644
index 00000000000..f579e7e2215
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-skip-if "-march given" { *-*-* } { "-march=*" } } */
+/* { dg-options "-mcpu=thead-c906" { target { rv64 } } } */
+/* T-Head XuanTie C906 => rv64imafdc */
+
+#if !((__riscv_xlen == 64)		\
+      && !defined(__riscv_32e)		\
+      && defined(__riscv_mul)		\
+      && defined(__riscv_atomic)	\
+      && (__riscv_flen == 64)		\
+      && defined(__riscv_compressed))
+#error "unexpected arch"
+#endif
+
+int main()
+{
+  return 0;
+}
-- 
2.38.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 3/7] riscv: thead: Add support for XTheadBa and XTheadBs ISA extensions
  2022-11-13 21:46 [PATCH 0/7] Add XThead* support Christoph Muellner
  2022-11-13 21:46 ` [PATCH 1/7] riscv: Add basic XThead* vendor extension support Christoph Muellner
  2022-11-13 21:46 ` [PATCH 2/7] riscv: riscv-cores.def: Add T-Head XuanTie C906 Christoph Muellner
@ 2022-11-13 21:46 ` Christoph Muellner
  2022-11-13 21:46 ` [PATCH 4/7] riscv: thead: Add support for XTheadCondMov " Christoph Muellner
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 20+ messages in thread
From: Christoph Muellner @ 2022-11-13 21:46 UTC (permalink / raw)
  To: gcc-patches, Kito Cheng, Jim Wilson, Palmer Dabbelt,
	Andrew Waterman, Philipp Tomsich, Cooper Qu, Lifang Xia,
	Yunhai Shang, Zhiwei Liu
  Cc: Christoph Müllner

From: Christoph Müllner <christoph.muellner@vrull.eu>

This patch adds support for the following T-Head vendor extensions:
* XTheadBa
* XTheadBs

Both extensions provide just one instruction, that has a counterpart
in the similar named Bitmanip ISA extension.

gcc/ChangeLog:

	* config/riscv/riscv.cc (riscv_rtx_costs): Adjust for th.tst.
	* config/riscv/riscv.md: Include thead.md.
	* config/riscv/thead.md: New file.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/xtheadba-addsl-64.c: New test.
	* gcc.target/riscv/xtheadba-addsl.c: New test.
	* gcc.target/riscv/xtheadbs-tst.c: New test.

Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
---
 gcc/config/riscv/riscv.cc                     |  4 +-
 gcc/config/riscv/riscv.md                     |  1 +
 gcc/config/riscv/thead.md                     | 38 +++++++++++++++++++
 .../gcc.target/riscv/xtheadba-addsl-64.c      | 18 +++++++++
 .../gcc.target/riscv/xtheadba-addsl.c         | 20 ++++++++++
 gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c | 12 ++++++
 6 files changed, 91 insertions(+), 2 deletions(-)
 create mode 100644 gcc/config/riscv/thead.md
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadba-addsl-64.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadba-addsl.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c

diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 02a01ca0b7c..decade0fedd 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2369,8 +2369,8 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
 	  *total = COSTS_N_INSNS (SINGLE_SHIFT_COST);
 	  return true;
 	}
-      /* bext pattern for zbs.  */
-      if (TARGET_ZBS && outer_code == SET
+      /* bit extraction pattern (zbs:bext, xtheadbs:tst).  */
+      if ((TARGET_ZBS || TARGET_XTHEADBS) && outer_code == SET
 	  && GET_CODE (XEXP (x, 1)) == CONST_INT
 	  && INTVAL (XEXP (x, 1)) == 1)
 	{
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 798f7370a08..a9254df7820 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -3009,3 +3009,4 @@ (define_insn "riscv_prefetchi_<mode>"
 (include "generic.md")
 (include "sifive-7.md")
 (include "vector.md")
+(include "thead.md")
diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
new file mode 100644
index 00000000000..676d10b71d7
--- /dev/null
+++ b/gcc/config/riscv/thead.md
@@ -0,0 +1,38 @@
+;; Machine description for T-Head vendor extensions
+;; Copyright (C) 2021-2022 Free Software Foundation, Inc.
+
+;; This file is part of GCC.
+
+;; GCC is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; GCC is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3.  If not see
+;; <http://www.gnu.org/licenses/>.
+
+(define_insn "*th_addsl"
+  [(set (match_operand:X 0 "register_operand" "=r")
+	(plus:X (ashift:X (match_operand:X 1 "register_operand" "r")
+			  (match_operand:QI 2 "immediate_operand" "I"))
+		(match_operand:X 3 "register_operand" "r")))]
+  "TARGET_XTHEADBA
+   && (INTVAL (operands[2]) >= 0) && (INTVAL (operands[2]) <= 3)"
+  "th.addsl\t%0,%1,%3,%2"
+  [(set_attr "type" "bitmanip")
+   (set_attr "mode" "<X:MODE>")])
+
+(define_insn "*th_tst"
+  [(set (match_operand:X 0 "register_operand" "=r")
+	(zero_extract:X (match_operand:X 1 "register_operand" "r")
+			(const_int 1)
+			(match_operand 2 "immediate_operand" "i")))]
+  "TARGET_XTHEADBS"
+  "th.tst\t%0,%1,%2"
+  [(set_attr "type" "bitmanip")])
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadba-addsl-64.c b/gcc/testsuite/gcc.target/riscv/xtheadba-addsl-64.c
new file mode 100644
index 00000000000..7f47929967a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadba-addsl-64.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xtheadba -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+/* RV64 only.  */
+int foos(short *x, int n){
+  return x[n];
+}
+int fooi(int *x, int n){
+  return x[n];
+}
+int fooll(long long *x, int n){
+  return x[n];
+}
+
+/* { dg-final { scan-assembler-times "th.addsl\[ \t\]*a\[0-9\]+,a\[0-9\]+,a\[0-9\]+,1" 1 } } */
+/* { dg-final { scan-assembler-times "th.addsl\[ \t\]*a\[0-9\]+,a\[0-9\]+,a\[0-9\]+,2" 1 } } */
+/* { dg-final { scan-assembler-times "th.addsl\[ \t\]*a\[0-9\]+,a\[0-9\]+,a\[0-9\]+,3" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadba-addsl.c b/gcc/testsuite/gcc.target/riscv/xtheadba-addsl.c
new file mode 100644
index 00000000000..d739f715430
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadba-addsl.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xtheadba -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+long test_1(long a, long b)
+{
+  return a + (b << 1);
+}
+long test_2(long a, long b)
+{
+  return a + (b << 2);
+}
+long test_3(long a, long b)
+{
+  return a + (b << 3);
+}
+
+/* { dg-final { scan-assembler-times "th.addsl\[ \t\]*a\[0-9\]+,a\[0-9\]+,a\[0-9\]+,1" 1 } } */
+/* { dg-final { scan-assembler-times "th.addsl\[ \t\]*a\[0-9\]+,a\[0-9\]+,a\[0-9\]+,2" 1 } } */
+/* { dg-final { scan-assembler-times "th.addsl\[ \t\]*a\[0-9\]+,a\[0-9\]+,a\[0-9\]+,3" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c b/gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c
new file mode 100644
index 00000000000..f4887bde535
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadbs-tst.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xtheadbs -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" } } */
+
+long
+foo1 (long i)
+{
+  return 1L & (i >> 20);
+}
+
+/* { dg-final { scan-assembler-times "th.tst\t" 1 } } */
+/* { dg-final { scan-assembler-not "andi" } } */
-- 
2.38.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 4/7] riscv: thead: Add support for XTheadCondMov ISA extensions
  2022-11-13 21:46 [PATCH 0/7] Add XThead* support Christoph Muellner
                   ` (2 preceding siblings ...)
  2022-11-13 21:46 ` [PATCH 3/7] riscv: thead: Add support for XTheadBa and XTheadBs ISA extensions Christoph Muellner
@ 2022-11-13 21:46 ` Christoph Muellner
  2022-11-13 21:46 ` [PATCH 5/7] riscv: thead: Add support for XTheadBb ISA extension Christoph Muellner
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 20+ messages in thread
From: Christoph Muellner @ 2022-11-13 21:46 UTC (permalink / raw)
  To: gcc-patches, Kito Cheng, Jim Wilson, Palmer Dabbelt,
	Andrew Waterman, Philipp Tomsich, Cooper Qu, Lifang Xia,
	Yunhai Shang, Zhiwei Liu
  Cc: Christoph Müllner

From: Christoph Müllner <christoph.muellner@vrull.eu>

This patch adds support for XTheadCondMov ISA extension.
The extension brings a one-sided conditional move (no else-assignment).
Given that GCC has a great if-conversion pass, we don't need to do much,
besides properly expanding mov<mode>cc accordingly and adjust the cost
model.

gcc/ChangeLog:

	* config/riscv/iterators.md (TARGET_64BIT): Add GPR2 iterator.
	* config/riscv/riscv.cc (riscv_rtx_costs): Add costs for
	  XTheadCondMov.
	(riscv_expand_conditional_move_onesided): New function.
	(riscv_expand_conditional_move): New function.
	* config/riscv/riscv.md: Add support for XTheadCondMov.
	* config/riscv/thead.md (*th_cond_mov<GPR:mode><GPR2:mode>): Add
	  support for XTheadCondMov.
	(*th_cond_gpr_mov<GPR:mode><GPR2:mode>): Likewise.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/xtheadcondmov-mveqz-imm-eqz.c: New test.
	* gcc.target/riscv/xtheadcondmov-mveqz-imm-not.c: New test.
	* gcc.target/riscv/xtheadcondmov-mveqz-reg-eqz.c: New test.
	* gcc.target/riscv/xtheadcondmov-mveqz-reg-not.c: New test.
	* gcc.target/riscv/xtheadcondmov-mvnez-imm-cond.c: New test.
	* gcc.target/riscv/xtheadcondmov-mvnez-imm-nez.c: New test.
	* gcc.target/riscv/xtheadcondmov-mvnez-reg-cond.c: New test.
	* gcc.target/riscv/xtheadcondmov-mvnez-reg-nez.c: New test.

Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
---
 gcc/config/riscv/iterators.md                 |  4 ++
 gcc/config/riscv/riscv.cc                     | 53 ++++++++++++++++---
 gcc/config/riscv/riscv.md                     |  7 +--
 gcc/config/riscv/thead.md                     | 35 ++++++++++++
 .../riscv/xtheadcondmov-mveqz-imm-eqz.c       | 37 +++++++++++++
 .../riscv/xtheadcondmov-mveqz-imm-not.c       | 37 +++++++++++++
 .../riscv/xtheadcondmov-mveqz-reg-eqz.c       | 37 +++++++++++++
 .../riscv/xtheadcondmov-mveqz-reg-not.c       | 37 +++++++++++++
 .../riscv/xtheadcondmov-mvnez-imm-cond.c      | 37 +++++++++++++
 .../riscv/xtheadcondmov-mvnez-imm-nez.c       | 37 +++++++++++++
 .../riscv/xtheadcondmov-mvnez-reg-cond.c      | 37 +++++++++++++
 .../riscv/xtheadcondmov-mvnez-reg-nez.c       | 37 +++++++++++++
 12 files changed, 386 insertions(+), 9 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-eqz.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-not.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-eqz.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-not.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-cond.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-nez.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-reg-cond.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-reg-nez.c

diff --git a/gcc/config/riscv/iterators.md b/gcc/config/riscv/iterators.md
index 50380ecfac9..3932eab14fa 100644
--- a/gcc/config/riscv/iterators.md
+++ b/gcc/config/riscv/iterators.md
@@ -26,6 +26,10 @@
 ;; from the same template.
 (define_mode_iterator GPR [SI (DI "TARGET_64BIT")])
 
+;; A copy of GPR that can be used when a pattern has two independent
+;; modes.
+(define_mode_iterator GPR2 [SI (DI "TARGET_64BIT")])
+
 ;; This mode iterator allows :P to be used for patterns that operate on
 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index decade0fedd..9a795264e00 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2269,8 +2269,8 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
       return false;
 
     case IF_THEN_ELSE:
-      if (TARGET_SFB_ALU
-	  && register_operand (XEXP (x, 1), mode)
+      if ((TARGET_SFB_ALU || TARGET_XTHEADCONDMOV)
+	  && reg_or_0_operand (XEXP (x, 1), mode)
 	  && sfb_alu_operand (XEXP (x, 2), mode)
 	  && comparison_operator (XEXP (x, 0), VOIDmode))
 	{
@@ -3231,16 +3231,57 @@ riscv_expand_conditional_branch (rtx label, rtx_code code, rtx op0, rtx op1)
   emit_jump_insn (gen_condjump (condition, label));
 }
 
+/* Helper to emit two one-sided conditional moves for the movecc.  */
+
+static void
+riscv_expand_conditional_move_onesided (rtx dest, rtx cons, rtx alt,
+					rtx_code code, rtx op0, rtx op1)
+{
+  machine_mode mode = GET_MODE (dest);
+
+  gcc_assert (GET_MODE_CLASS (mode) == MODE_INT);
+  gcc_assert (reg_or_0_operand (cons, mode));
+  gcc_assert (reg_or_0_operand (alt, mode));
+
+  riscv_emit_int_compare (&code, &op0, &op1);
+  rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
+
+  rtx tmp1 = gen_reg_rtx (mode);
+  rtx tmp2 = gen_reg_rtx (mode);
+
+  emit_insn (gen_rtx_SET (tmp1, gen_rtx_IF_THEN_ELSE (mode, cond,
+						      cons, const0_rtx)));
+
+  /* We need to expand a sequence for both blocks and we do that such,
+     that the second conditional move will use the inverted condition.
+     We use temporaries that are or'd to the dest register.  */
+  cond = gen_rtx_fmt_ee ((code == EQ) ? NE : EQ, GET_MODE (op0), op0, op1);
+  emit_insn (gen_rtx_SET (tmp2, gen_rtx_IF_THEN_ELSE (mode, cond,
+						      alt, const0_rtx)));
+
+  emit_insn (gen_rtx_SET (dest, gen_rtx_IOR (mode, tmp1, tmp2)));
+ }
+
 /* If (CODE OP0 OP1) holds, move CONS to DEST; else move ALT to DEST.  */
 
 void
 riscv_expand_conditional_move (rtx dest, rtx cons, rtx alt, rtx_code code,
 			       rtx op0, rtx op1)
 {
-  riscv_emit_int_compare (&code, &op0, &op1);
-  rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
-  emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (GET_MODE (dest), cond,
-						      cons, alt)));
+  machine_mode mode = GET_MODE (dest);
+
+  if (TARGET_XTHEADCONDMOV
+      && GET_MODE_CLASS (mode) == MODE_INT
+      && reg_or_0_operand (cons, mode)
+      && reg_or_0_operand (alt, mode))
+    riscv_expand_conditional_move_onesided (dest, cons, alt, code, op0, op1);
+  else
+    {
+      riscv_emit_int_compare (&code, &op0, &op1);
+      rtx cond = gen_rtx_fmt_ee (code, GET_MODE (op0), op0, op1);
+      emit_insn (gen_rtx_SET (dest, gen_rtx_IF_THEN_ELSE (GET_MODE (dest),
+							  cond, cons, alt)));
+    }
 }
 
 /* Implement TARGET_FUNCTION_ARG_BOUNDARY.  Every parameter gets at
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index a9254df7820..850a2d958e4 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -233,6 +233,7 @@ (define_attr "enabled" "no,yes"
 ;; nop		no operation
 ;; ghost	an instruction that produces no real code
 ;; bitmanip	bit manipulation instructions
+;; condmove	conditional moves
 ;; Classification of RVV instructions which will be added to each RVV .md pattern and used by scheduler.
 ;; rdvlenb     vector byte length vlenb csrr read
 ;; rdvl        vector length vl csrr read
@@ -324,7 +325,7 @@ (define_attr "type"
   "unknown,branch,jump,call,load,fpload,store,fpstore,
    mtc,mfc,const,arith,logical,shift,slt,imul,idiv,move,fmove,fadd,fmul,
    fmadd,fdiv,fcmp,fcvt,fsqrt,multi,auipc,sfb_alu,nop,ghost,bitmanip,rotate,
-   atomic,rdvlenb,rdvl,vsetvl,vlde,vste,vldm,vstm,vlds,vsts,
+   atomic,condmove,rdvlenb,rdvl,vsetvl,vlde,vste,vldm,vstm,vlds,vsts,
    vldux,vldox,vstux,vstox,vldff,vldr,vstr,
    vialu,viwalu,vext,vicalu,vshift,vnshift,vicmp,
    vimul,vidiv,viwmul,vimuladd,viwmuladd,vimerge,vimov,
@@ -2223,9 +2224,9 @@ (define_insn "*branch<mode>"
 (define_expand "mov<mode>cc"
   [(set (match_operand:GPR 0 "register_operand")
 	(if_then_else:GPR (match_operand 1 "comparison_operator")
-			  (match_operand:GPR 2 "register_operand")
+			  (match_operand:GPR 2 "reg_or_0_operand")
 			  (match_operand:GPR 3 "sfb_alu_operand")))]
-  "TARGET_SFB_ALU"
+  "TARGET_SFB_ALU || TARGET_XTHEADCONDMOV"
 {
   rtx cmp = operands[1];
   /* We only handle word mode integer compares for now.  */
diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
index 676d10b71d7..e9a6c1eeb71 100644
--- a/gcc/config/riscv/thead.md
+++ b/gcc/config/riscv/thead.md
@@ -36,3 +36,38 @@ (define_insn "*th_tst"
   "TARGET_XTHEADBS"
   "th.tst\t%0,%1,%2"
   [(set_attr "type" "bitmanip")])
+
+(define_insn "*th_cond_mov<GPR:mode><GPR2:mode>"
+  [(set (match_operand:GPR 0 "register_operand" "=r,r")
+	(if_then_else:GPR
+	 (match_operator 4 "equality_operator"
+		[(match_operand:GPR2 1 "register_operand" "r,r")
+		 (const_int 0)])
+	 (match_operand:GPR 2 "reg_or_0_operand" "rJ,0")
+	 (match_operand:GPR 3 "reg_or_0_operand" "0,rJ")))]
+  "TARGET_XTHEADCONDMOV"
+{
+  if (which_alternative == 0)
+    return "th.mv%C4z\t%0,%z2,%1";
+
+  /* Invert the condition and take else-block.  */
+  rtx_code code = GET_CODE (operands[4]);
+  code = (code == EQ) ? NE : EQ;
+  operands[4] = gen_rtx_fmt_ee (code, VOIDmode, const0_rtx, const0_rtx);
+  return "th.mv%C4z\t%0,%z3,%1";
+}
+  [(set_attr "type" "condmove")
+   (set_attr "mode" "<GPR:MODE>")])
+
+(define_insn "*th_cond_gpr_mov<GPR:mode><GPR2:mode>"
+  [(set (match_operand:GPR 0 "register_operand" "=r,r")
+	(if_then_else:GPR
+	 (match_operand:GPR2 1 "register_operand" "r,r")
+	 (match_operand:GPR 2 "reg_or_0_operand" "rJ,0")
+	 (match_operand:GPR 3 "reg_or_0_operand" "0,rJ")))]
+  "TARGET_XTHEADCONDMOV"
+  "@
+   th.mvnez\t%0,%z2,%1
+   th.mveqz\t%0,%z3,%1"
+  [(set_attr "type" "condmove")
+   (set_attr "mode" "<GPR:MODE>")])
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-eqz.c b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-eqz.c
new file mode 100644
index 00000000000..c66ec7fadbb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-eqz.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */
+
+int
+not_int_int (int x, int cond)
+{
+  if (cond == 0)
+    return 1025;
+  return x;
+}
+
+long
+not_long_int (long x, int cond)
+{
+  if (cond == 0)
+    return 1025l;
+  return x;
+}
+
+int
+not_int_long (int x, long cond)
+{
+  if (cond == 0)
+    return 1025;
+  return x;
+}
+
+long
+not_long_long (long x, int cond)
+{
+  if (cond == 0)
+    return 1025l;
+  return x;
+}
+
+/* { dg-final { scan-assembler-times "th.mveqz" 4 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-not.c b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-not.c
new file mode 100644
index 00000000000..c076dbca4ef
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-imm-not.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mabi=lp64 -O2" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */
+
+int
+not_int_int (int x, int cond)
+{
+  if (!cond)
+    return 1025;
+  return x;
+}
+
+long
+not_long_int (long x, int cond)
+{
+  if (!cond)
+    return 1025l;
+  return x;
+}
+
+int
+not_int_long (int x, long cond)
+{
+  if (!cond)
+    return 1025;
+  return x;
+}
+
+long
+not_long_long (long x, int cond)
+{
+  if (!cond)
+    return 1025l;
+  return x;
+}
+
+/* { dg-final { scan-assembler-times "th.mveqz" 4 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-eqz.c b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-eqz.c
new file mode 100644
index 00000000000..3e2e369bdb2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-eqz.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */
+
+int
+not_int_int (int x, int cond, int v)
+{
+  if (cond == 0)
+    return v;
+  return x;
+}
+
+long
+not_long_int (long x, int cond, long v)
+{
+  if (cond == 0)
+    return v;
+  return x;
+}
+
+int
+not_int_long (int x, long cond, int v)
+{
+  if (cond == 0)
+    return v;
+  return x;
+}
+
+long
+not_long_long (long x, int cond, long v)
+{
+  if (cond == 0)
+    return v;
+  return x;
+}
+
+/* { dg-final { scan-assembler-times "th.mveqz" 4 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-not.c b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-not.c
new file mode 100644
index 00000000000..c387d1c5f98
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mveqz-reg-not.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mabi=lp64 -O2" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */
+
+int
+not_int_int (int x, int cond, int v)
+{
+  if (!cond)
+    return v;
+  return x;
+}
+
+long
+not_long_int (long x, int cond, long v)
+{
+  if (!cond)
+    return v;
+  return x;
+}
+
+int
+not_int_long (int x, long cond, int v)
+{
+  if (!cond)
+    return v;
+  return x;
+}
+
+long
+not_long_long (long x, int cond, long v)
+{
+  if (!cond)
+    return v;
+  return x;
+}
+
+/* { dg-final { scan-assembler-times "th.mveqz" 4 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-cond.c b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-cond.c
new file mode 100644
index 00000000000..95b396057da
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-cond.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mabi=lp64 -O2" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */
+
+int
+not_int_int (int x, int cond)
+{
+  if (cond)
+    return 1025;
+  return x;
+}
+
+long
+not_long_int (long x, int cond)
+{
+  if (cond)
+    return 1025l;
+  return x;
+}
+
+int
+not_int_long (int x, long cond)
+{
+  if (cond)
+    return 1025;
+  return x;
+}
+
+long
+not_long_long (long x, int cond)
+{
+  if (cond)
+    return 1025l;
+  return x;
+}
+
+/* { dg-final { scan-assembler-times "th.mvnez" 4 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-nez.c b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-nez.c
new file mode 100644
index 00000000000..cc17f1bd82d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-imm-nez.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */
+
+int
+not_int_int (int x, int cond)
+{
+  if (cond != 0)
+    return 1025;
+  return x;
+}
+
+long
+not_long_int (long x, int cond)
+{
+  if (cond != 0)
+    return 1025l;
+  return x;
+}
+
+int
+not_int_long (int x, long cond)
+{
+  if (cond != 0)
+    return 1025;
+  return x;
+}
+
+long
+not_long_long (long x, int cond)
+{
+  if (cond != 0)
+    return 1025l;
+  return x;
+}
+
+/* { dg-final { scan-assembler-times "th.mvnez" 4 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-reg-cond.c b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-reg-cond.c
new file mode 100644
index 00000000000..732e892875b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-reg-cond.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mabi=lp64 -O2" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */
+
+int
+not_int_int (int x, int cond, int v)
+{
+  if (cond)
+    return v;
+  return x;
+}
+
+long
+not_long_int (long x, int cond, long v)
+{
+  if (cond)
+    return v;
+  return x;
+}
+
+int
+not_int_long (int x, long cond, int v)
+{
+  if (cond)
+    return v;
+  return x;
+}
+
+long
+not_long_long (long x, int cond, long v)
+{
+  if (cond)
+    return v;
+  return x;
+}
+
+/* { dg-final { scan-assembler-times "th.mvnez" 4 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-reg-nez.c b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-reg-nez.c
new file mode 100644
index 00000000000..e369a972a16
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadcondmov-mvnez-reg-nez.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xtheadcondmov -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */
+
+int
+not_int_int (int x, int cond, int v)
+{
+  if (cond != 0)
+    return v;
+  return x;
+}
+
+long
+not_long_int (long x, int cond, long v)
+{
+  if (cond != 0)
+    return v;
+  return x;
+}
+
+int
+not_int_long (int x, long cond, int v)
+{
+  if (cond != 0)
+    return v;
+  return x;
+}
+
+long
+not_long_long (long x, int cond, long v)
+{
+  if (cond != 0)
+    return v;
+  return x;
+}
+
+/* { dg-final { scan-assembler-times "th.mvnez" 4 } } */
-- 
2.38.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 5/7] riscv: thead: Add support for XTheadBb ISA extension
  2022-11-13 21:46 [PATCH 0/7] Add XThead* support Christoph Muellner
                   ` (3 preceding siblings ...)
  2022-11-13 21:46 ` [PATCH 4/7] riscv: thead: Add support for XTheadCondMov " Christoph Muellner
@ 2022-11-13 21:46 ` Christoph Muellner
  2022-11-18  4:21   ` cooper.qu
  2022-11-13 21:46 ` [PATCH 6/7] riscv: thead: Add support for XTheadMac " Christoph Muellner
  2022-11-13 21:46 ` [PATCH 7/7] riscv: Add basic extension support for XTheadFmv and XTheadInt Christoph Muellner
  6 siblings, 1 reply; 20+ messages in thread
From: Christoph Muellner @ 2022-11-13 21:46 UTC (permalink / raw)
  To: gcc-patches, Kito Cheng, Jim Wilson, Palmer Dabbelt,
	Andrew Waterman, Philipp Tomsich, Cooper Qu, Lifang Xia,
	Yunhai Shang, Zhiwei Liu
  Cc: Christoph Müllner

From: Christoph Müllner <christoph.muellner@vrull.eu>

The XTheadBb ISA extension provides instructions similar to Zbb:
* th.srri/th.srriw
* th.ext/th.extu
* th.ff1 (count-leading-zeros)
* th.rev/th.revw

Instructions that are not covered, because they don't fit into a
pattern:
* th.ff0 (count-leading-ones)
* th.tstnbz

For the cases where the RISC-V backend already provides instruction
patterns with GCC standard pattern names (e.g. rotatert<mode>), this
patch simply uses expanders so we can match the pattern using unnamed
instruction patterns for zb* and xtheadb*.

gcc/ChangeLog:

	* config/riscv/bitmanip.md (clz<mode>2): Add expand.
	(ctz<mode>2): Add expand.
	(popcount<mode>2): Add expand.
	(*<bitmanip_optab>si2): Hide pattern name.
	(*<bitmanip_optab>di2): Hide pattern name.
	(rotr<mode>3): Add expand.
	(*rotrsi3): Hide pattern name.
	(*rotrdi3): Hide pattern name.
	(*rotrsi3_sext): Hide pattern name.
	(bswapdi2): Add expand.
	(bswapsi2): Add expand.
	(*bswap<mode>2): Hide pattern name.
	* config/riscv/riscv.cc (riscv_rtx_costs): Add support for
	  sign-extract.
	* config/riscv/riscv.md (extv<mode>): New expand.
	(extzv<mode>): New expand.
	* config/riscv/thead.md (*th_srrisi3): New pattern.
	(*th_srridi3): New pattern.
	(*th_ext<mode>): New pattern.
	(*th_extu<mode>): New pattern.
	(*th_clz<mode>): New pattern.
	(*th_revsi2): New pattern.
	(*th_revdi2): New pattern.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/xtheadbb-ext.c: New test.
	* gcc.target/riscv/xtheadbb-extu.c: New test.
	* gcc.target/riscv/xtheadbb-rev.c: New test.
	* gcc.target/riscv/xtheadbb-srri.c: New test.

Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
---
 gcc/config/riscv/bitmanip.md                  | 47 ++++++++++++--
 gcc/config/riscv/riscv.cc                     | 10 +++
 gcc/config/riscv/riscv.md                     | 26 ++++++++
 gcc/config/riscv/thead.md                     | 62 +++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/xtheadbb-ext.c | 19 ++++++
 .../gcc.target/riscv/xtheadbb-extu.c          | 12 ++++
 gcc/testsuite/gcc.target/riscv/xtheadbb-rev.c | 40 ++++++++++++
 .../gcc.target/riscv/xtheadbb-srri.c          | 18 ++++++
 8 files changed, 228 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-ext.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-extu.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-rev.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-srri.c

diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md
index b44fb9517e7..3dbb92b6115 100644
--- a/gcc/config/riscv/bitmanip.md
+++ b/gcc/config/riscv/bitmanip.md
@@ -119,6 +119,21 @@ (define_insn "*slliuw"
 
 ;; ZBB extension.
 
+(define_expand "clz<mode>2"
+  [(set (match_operand:GPR 0 "register_operand")
+	(clz:GPR (match_operand:GPR 1 "register_operand")))]
+  "TARGET_ZBB || TARGET_XTHEADBB")
+
+(define_expand "ctz<mode>2"
+  [(set (match_operand:GPR 0 "register_operand")
+	(ctz:GPR (match_operand:GPR 1 "register_operand")))]
+  "TARGET_ZBB")
+
+(define_expand "popcount<mode>2"
+  [(set (match_operand:GPR 0 "register_operand")
+	(popcount:GPR (match_operand:GPR 1 "register_operand")))]
+  "TARGET_ZBB")
+
 (define_insn "*<optab>_not<mode>"
   [(set (match_operand:X 0 "register_operand" "=r")
         (bitmanip_bitwise:X (not:X (match_operand:X 1 "register_operand" "r"))
@@ -137,7 +152,7 @@ (define_insn "*xor_not<mode>"
   [(set_attr "type" "bitmanip")
    (set_attr "mode" "<X:MODE>")])
 
-(define_insn "<bitmanip_optab>si2"
+(define_insn "*<bitmanip_optab>si2"
   [(set (match_operand:SI 0 "register_operand" "=r")
         (clz_ctz_pcnt:SI (match_operand:SI 1 "register_operand" "r")))]
   "TARGET_ZBB"
@@ -154,7 +169,7 @@ (define_insn "*<bitmanip_optab>disi2"
   [(set_attr "type" "bitmanip")
    (set_attr "mode" "SI")])
 
-(define_insn "<bitmanip_optab>di2"
+(define_insn "*<bitmanip_optab>di2"
   [(set (match_operand:DI 0 "register_operand" "=r")
         (clz_ctz_pcnt:DI (match_operand:DI 1 "register_operand" "r")))]
   "TARGET_64BIT && TARGET_ZBB"
@@ -194,7 +209,17 @@ (define_insn "*zero_extendhi<GPR:mode>2_zbb"
   [(set_attr "type" "bitmanip,load")
    (set_attr "mode" "HI")])
 
-(define_insn "rotrsi3"
+(define_expand "rotr<mode>3"
+  [(set (match_operand:GPR 0 "register_operand")
+	(rotatert:GPR (match_operand:GPR 1 "register_operand")
+		     (match_operand:QI 2 "arith_operand")))]
+  "TARGET_ZBB || TARGET_XTHEADBB"
+{
+  if (TARGET_XTHEADBB && !immediate_operand (operands[2], VOIDmode))
+    FAIL;
+})
+
+(define_insn "*rotrsi3"
   [(set (match_operand:SI 0 "register_operand" "=r")
 	(rotatert:SI (match_operand:SI 1 "register_operand" "r")
 		     (match_operand:QI 2 "arith_operand" "rI")))]
@@ -202,7 +227,7 @@ (define_insn "rotrsi3"
   "ror%i2%~\t%0,%1,%2"
   [(set_attr "type" "bitmanip")])
 
-(define_insn "rotrdi3"
+(define_insn "*rotrdi3"
   [(set (match_operand:DI 0 "register_operand" "=r")
 	(rotatert:DI (match_operand:DI 1 "register_operand" "r")
 		     (match_operand:QI 2 "arith_operand" "rI")))]
@@ -210,7 +235,7 @@ (define_insn "rotrdi3"
   "ror%i2\t%0,%1,%2"
   [(set_attr "type" "bitmanip")])
 
-(define_insn "rotrsi3_sext"
+(define_insn "*rotrsi3_sext"
   [(set (match_operand:DI 0 "register_operand" "=r")
 	(sign_extend:DI (rotatert:SI (match_operand:SI 1 "register_operand" "r")
 				     (match_operand:QI 2 "register_operand" "r"))))]
@@ -242,7 +267,17 @@ (define_insn "rotlsi3_sext"
   "rolw\t%0,%1,%2"
   [(set_attr "type" "bitmanip")])
 
-(define_insn "bswap<mode>2"
+(define_expand "bswapdi2"
+  [(set (match_operand:DI 0 "register_operand")
+	(bswap:DI (match_operand:DI 1 "register_operand")))]
+  "TARGET_64BIT && (TARGET_ZBB || TARGET_XTHEADBB)")
+
+(define_expand "bswapsi2"
+  [(set (match_operand:SI 0 "register_operand")
+	(bswap:SI (match_operand:SI 1 "register_operand")))]
+  "(!TARGET_64BIT && TARGET_ZBB) || TARGET_XTHEADBB")
+
+(define_insn "*bswap<mode>2"
   [(set (match_operand:X 0 "register_operand" "=r")
         (bswap:X (match_operand:X 1 "register_operand" "r")))]
   "TARGET_ZBB"
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 9a795264e00..c0de99d1ca6 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -2377,6 +2377,16 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN
 	  *total = COSTS_N_INSNS (SINGLE_SHIFT_COST);
 	  return true;
 	}
+      /* Fall through.  */
+    case SIGN_EXTRACT:
+      if (TARGET_XTHEADBB
+	  && REG_P (XEXP (x, 0))
+	  && CONST_INT_P (XEXP (x, 1))
+	  && CONST_INT_P (XEXP (x, 2)))
+	{
+	  *total = COSTS_N_INSNS (SINGLE_SHIFT_COST);
+	  return true;
+	}
       return false;
 
     case ASHIFT:
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 850a2d958e4..cfe1fd6baea 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -3003,6 +3003,32 @@ (define_insn "riscv_prefetchi_<mode>"
   "prefetch.i\t%a0"
 )
 
+(define_expand "extv<mode>"
+  [(set (match_operand:GPR 0 "register_operand" "=r")
+	(sign_extract:GPR (match_operand:GPR 1 "register_operand" "r")
+			 (match_operand 2 "const_int_operand")
+			 (match_operand 3 "const_int_operand")))]
+  "TARGET_XTHEADBB"
+{
+  if (TARGET_XTHEADBB
+      && ((INTVAL (operands[2]) + INTVAL (operands[3]))
+	  >= GET_MODE_BITSIZE (GET_MODE (operands[1])).to_constant ()))
+    FAIL;
+})
+
+(define_expand "extzv<mode>"
+  [(set (match_operand:GPR 0 "register_operand" "=r")
+	(zero_extract:GPR (match_operand:GPR 1 "register_operand" "r")
+			 (match_operand 2 "const_int_operand")
+			 (match_operand 3 "const_int_operand")))]
+  "TARGET_XTHEADBB"
+{
+  if (TARGET_XTHEADBB
+      && ((INTVAL (operands[2]) + INTVAL (operands[3]))
+	  >= GET_MODE_BITSIZE (GET_MODE (operands[1])).to_constant ()))
+    FAIL;
+})
+
 (include "bitmanip.md")
 (include "sync.md")
 (include "peephole.md")
diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
index e9a6c1eeb71..ad42c03c0ce 100644
--- a/gcc/config/riscv/thead.md
+++ b/gcc/config/riscv/thead.md
@@ -28,6 +28,68 @@ (define_insn "*th_addsl"
   [(set_attr "type" "bitmanip")
    (set_attr "mode" "<X:MODE>")])
 
+(define_insn "*th_srrisi3"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(rotatert:SI (match_operand:SI 1 "register_operand" "r")
+		     (match_operand:QI 2 "immediate_operand" "I")))]
+  "TARGET_XTHEADBB"
+  { return TARGET_64BIT ? "th.srriw\t%0,%1,%2" : "th.srri\t%0,%1,%2"; }
+  [(set_attr "type" "bitmanip")])
+
+(define_insn "*th_srridi3"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+	(rotatert:DI (match_operand:DI 1 "register_operand" "r")
+		     (match_operand:QI 2 "immediate_operand" "I")))]
+  "TARGET_XTHEADBB && TARGET_64BIT"
+  "th.srri\t%0,%1,%2"
+  [(set_attr "type" "bitmanip")])
+
+(define_insn "*th_ext<mode>"
+  [(set (match_operand:X 0 "register_operand" "=r")
+	(sign_extract:X (match_operand:X 1 "register_operand" "r")
+			(match_operand 2 "const_int_operand")
+			(match_operand 3 "const_int_operand")))]
+  "TARGET_XTHEADBB"
+{
+  operands[3] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
+  return "th.ext\t%0,%1,%2,%3";
+}
+  [(set_attr "type" "bitmanip")])
+
+(define_insn "*th_extu<mode>"
+  [(set (match_operand:X 0 "register_operand" "=r")
+	(zero_extract:X (match_operand:X 1 "register_operand" "r")
+			(match_operand 2 "const_int_operand")
+			(match_operand 3 "const_int_operand")))]
+  "TARGET_XTHEADBB"
+{
+  operands[3] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
+  return "th.extu\t%0,%1,%2,%3";
+}
+  [(set_attr "type" "bitmanip")])
+
+(define_insn "*th_clz<mode>"
+  [(set (match_operand:X 0 "register_operand" "=r")
+	(clz:X (match_operand:X 1 "register_operand" "r")))]
+  "TARGET_XTHEADBB"
+  "th.ff1\t%0,%1"
+  [(set_attr "type" "bitmanip")
+   (set_attr "mode" "<X:MODE>")])
+
+(define_insn "*th_revsi2"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(bswap:SI (match_operand:SI 1 "register_operand" "r")))]
+  "TARGET_XTHEADBB"
+  { return TARGET_64BIT ? "th.revw\t%0,%1" : "th.rev\t%0,%1"; }
+  [(set_attr "type" "bitmanip")])
+
+(define_insn "*th_revdi2"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+	(bswap:DI (match_operand:DI 1 "register_operand" "r")))]
+  "TARGET_XTHEADBB && TARGET_64BIT"
+  "th.rev\t%0,%1"
+  [(set_attr "type" "bitmanip")])
+
 (define_insn "*th_tst"
   [(set (match_operand:X 0 "register_operand" "=r")
 	(zero_extract:X (match_operand:X 1 "register_operand" "r")
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb-ext.c b/gcc/testsuite/gcc.target/riscv/xtheadbb-ext.c
new file mode 100644
index 00000000000..35c3afa5aad
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-ext.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xtheadbb -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */
+
+struct bar
+{
+  long a:18;
+  long b:24;
+  long c:22;
+};
+
+long
+foo (struct bar *s)
+{
+  return s->b;
+}
+
+/* { dg-final { scan-assembler "ext\t" } } */
+/* { dg-final { scan-assembler-not "andi" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb-extu.c b/gcc/testsuite/gcc.target/riscv/xtheadbb-extu.c
new file mode 100644
index 00000000000..d52af1dec61
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-extu.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xtheadbb -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */
+
+int
+foo (int a, int b)
+{
+  return ((a & (1 << 25)) ? 5 : 4);
+}
+
+/* { dg-final { scan-assembler "extu\t" } } */
+/* { dg-final { scan-assembler-not "andi" } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb-rev.c b/gcc/testsuite/gcc.target/riscv/xtheadbb-rev.c
new file mode 100644
index 00000000000..fb35317ae9f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-rev.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xtheadbb -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+unsigned int
+foo32 (unsigned int x)
+{
+  return (((x << 24) & 0xff000000)
+	  | ((x << 8) & 0xff0000)
+	  | ((x >> 8) & 0xff00)
+	  | ((x >> 24) & 0xff));
+}
+
+unsigned int
+foo32_1 (unsigned int x)
+{
+  return __builtin_bswap32 (x);
+}
+
+unsigned long
+foo64 (unsigned long x)
+{
+  return (((x << 56) & 0xff00000000000000ull)
+	  | ((x << 40) & 0xff000000000000ull)
+	  | ((x << 24) & 0xff0000000000ull)
+	  | ((x << 8) & 0xff00000000ull)
+	  | ((x >> 8) & 0xff000000)
+	  | ((x >> 24) & 0xff0000)
+	  | ((x >> 40) & 0xff00)
+	  | ((x >> 56) & 0xff));
+}
+
+unsigned long
+foo64_1 (unsigned long x)
+{
+  return __builtin_bswap64 (x);
+}
+
+/* { dg-final { scan-assembler-times "th.revw\t" 2 } } */
+/* { dg-final { scan-assembler-times "th.rev\t" 2 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb-srri.c b/gcc/testsuite/gcc.target/riscv/xtheadbb-srri.c
new file mode 100644
index 00000000000..cd992ae3f0a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-srri.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv64gc_xtheadbb -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-g" } } */
+
+unsigned long foo1(unsigned long rs1)
+{
+    long shamt = __riscv_xlen - 11;
+    return (rs1 << shamt) |
+	   (rs1 >> ((__riscv_xlen - shamt) & (__riscv_xlen - 1)));
+}
+unsigned long foo2(unsigned long rs1)
+{
+    unsigned long shamt = __riscv_xlen - 11;
+    return (rs1 >> shamt) |
+	   (rs1 << ((__riscv_xlen - shamt) & (__riscv_xlen - 1)));
+}
+
+/* { dg-final { scan-assembler-times "th.srri" 2 } } */
-- 
2.38.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 6/7] riscv: thead: Add support for XTheadMac ISA extension
  2022-11-13 21:46 [PATCH 0/7] Add XThead* support Christoph Muellner
                   ` (4 preceding siblings ...)
  2022-11-13 21:46 ` [PATCH 5/7] riscv: thead: Add support for XTheadBb ISA extension Christoph Muellner
@ 2022-11-13 21:46 ` Christoph Muellner
  2022-11-13 21:46 ` [PATCH 7/7] riscv: Add basic extension support for XTheadFmv and XTheadInt Christoph Muellner
  6 siblings, 0 replies; 20+ messages in thread
From: Christoph Muellner @ 2022-11-13 21:46 UTC (permalink / raw)
  To: gcc-patches, Kito Cheng, Jim Wilson, Palmer Dabbelt,
	Andrew Waterman, Philipp Tomsich, Cooper Qu, Lifang Xia,
	Yunhai Shang, Zhiwei Liu
  Cc: Christoph Müllner, quxm

From: Christoph Müllner <christoph.muellner@vrull.eu>

The XTheadMac ISA extension provides multiply-accumulate/subtract
instructions:
* mula/mulaw/mulah
* muls/mulsw/mulsh

To benefit from middle-end passes, we expand the following named
patterns in riscv.md (as they are not T-Head-specific):
* maddhisi4
* msubhisi4

gcc/ChangeLog:

	* config/riscv/riscv.md (maddhisi4): New expand.
	(msubhisi4): New expand.
	* config/riscv/thead.md (*th_mula<mode>): New pattern.
	(*th_mulawsi): New pattern.
	(*th_mulawsi2): New pattern.
	(*th_maddhisi4): New pattern.
	(*th_sextw_maddhisi4): New pattern.
	(*th_muls<mode>): New pattern.
	(*th_mulswsi): New pattern.
	(*th_mulswsi2): New pattern.
	(*th_msubhisi4): New pattern.
	(*th_sextw_msubhisi4): New pattern.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/thead-mula-1.c: New test.
	* gcc.target/riscv/thead-mula-2.c: New test.

Co-Developed-by: quxm <xianmiao.qxm@alibaba-inc.com>
Signed-off-by: quxm <xianmiao.qxm@alibaba-inc.com>
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
---
 gcc/config/riscv/riscv.md                     |  18 +++
 gcc/config/riscv/thead.md                     | 117 ++++++++++++++++++
 gcc/testsuite/gcc.target/riscv/thead-mula-1.c |  40 ++++++
 gcc/testsuite/gcc.target/riscv/thead-mula-2.c |  28 +++++
 4 files changed, 203 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/riscv/thead-mula-1.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/thead-mula-2.c

diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index cfe1fd6baea..998169115f2 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -3029,6 +3029,24 @@ (define_expand "extzv<mode>"
     FAIL;
 })
 
+(define_expand "maddhisi4"
+  [(set (match_operand:SI 0 "register_operand")
+	(plus:SI
+	  (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand"))
+		   (sign_extend:SI (match_operand:HI 2 "register_operand")))
+	  (match_operand:SI 3 "register_operand")))]
+  "TARGET_XTHEADMAC"
+)
+
+(define_expand "msubhisi4"
+  [(set (match_operand:SI 0 "register_operand")
+	(minus:SI
+	  (match_operand:SI 3 "register_operand")
+	  (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand"))
+		   (sign_extend:SI (match_operand:HI 2 "register_operand")))))]
+  "TARGET_XTHEADMAC"
+)
+
 (include "bitmanip.md")
 (include "sync.md")
 (include "peephole.md")
diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
index ad42c03c0ce..f31ba18aa84 100644
--- a/gcc/config/riscv/thead.md
+++ b/gcc/config/riscv/thead.md
@@ -133,3 +133,120 @@ (define_insn "*th_cond_gpr_mov<GPR:mode><GPR2:mode>"
    th.mveqz\t%0,%z3,%1"
   [(set_attr "type" "condmove")
    (set_attr "mode" "<GPR:MODE>")])
+
+;; XTheadMac
+
+(define_insn "*th_mula<mode>"
+  [(set (match_operand:X 0 "register_operand" "=r")
+	      (plus:X (mult:X (match_operand:X 1 "register_operand" "r")
+			      (match_operand:X 2 "register_operand" "r"))
+		      (match_operand:X 3 "register_operand" "0")))]
+  "TARGET_XTHEADMAC"
+  "th.mula\\t%0,%1,%2"
+  [(set_attr "type" "imul")
+   (set_attr "mode" "<MODE>")]
+)
+
+(define_insn "*th_mulawsi"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+	(sign_extend:DI
+	  (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
+			    (match_operand:SI 2 "register_operand" "r"))
+		   (match_operand:SI 3 "register_operand" "0"))))]
+  "TARGET_XTHEADMAC && TARGET_64BIT"
+  "th.mulaw\\t%0,%1,%2"
+  [(set_attr "type" "imul")
+   (set_attr "mode" "SI")]
+)
+
+(define_insn "*th_mulawsi2"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	      (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
+				(match_operand:SI 2 "register_operand" "r"))
+		       (match_operand:SI 3 "register_operand" "0")))]
+  "TARGET_XTHEADMAC && TARGET_64BIT"
+  "mulaw\\t%0,%1,%2"
+  [(set_attr "type" "imul")
+   (set_attr "mode" "SI")]
+)
+
+(define_insn "*th_maddhisi4"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(plus:SI (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" " r"))
+			  (sign_extend:SI (match_operand:HI 2 "register_operand" " r")))
+		 (match_operand:SI 3 "register_operand" " 0")))]
+  "TARGET_XTHEADMAC"
+  "th.mulah\\t%0,%1,%2"
+  [(set_attr "type" "imul")
+   (set_attr "mode" "SI")]
+)
+
+(define_insn "*th_sextw_maddhisi4"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+	(sign_extend:DI
+	  (plus:SI (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" " r"))
+			    (sign_extend:SI (match_operand:HI 2 "register_operand" " r")))
+		   (match_operand:SI 3 "register_operand" " 0"))))]
+  "TARGET_XTHEADMAC && TARGET_64BIT"
+  "th.mulah\\t%0,%1,%2"
+  [(set_attr "type" "imul")
+   (set_attr "mode" "SI")]
+)
+
+(define_insn "*th_muls<mode>"
+  [(set (match_operand:X 0 "register_operand" "=r")
+	      (minus:X (match_operand:X 3 "register_operand" "0")
+		       (mult:X (match_operand:X 1 "register_operand" "r")
+			       (match_operand:X 2 "register_operand" "r"))))]
+  "TARGET_XTHEADMAC"
+  "th.muls\\t%0,%1,%2"
+  [(set_attr "type" "imul")
+   (set_attr "mode" "<MODE>")]
+)
+
+(define_insn "*th_mulswsi"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+	(sign_extend:DI
+	  (minus:SI (match_operand:SI 3 "register_operand" "0")
+		    (mult:SI (match_operand:SI 1 "register_operand" "r")
+			     (match_operand:SI 2 "register_operand" "r")))))]
+  "TARGET_XTHEADMAC && TARGET_64BIT"
+  "th.mulsw\\t%0,%1,%2"
+  [(set_attr "type" "imul")
+   (set_attr "mode" "SI")]
+)
+
+(define_insn "*th_mulswsi2"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(minus:SI (match_operand:SI 3 "register_operand" "0")
+		  (mult:SI (match_operand:SI 1 "register_operand" "r")
+			   (match_operand:SI 2 "register_operand" "r"))))]
+  "TARGET_XTHEADMAC && TARGET_64BIT"
+  "th.mulsw\\t%0,%1,%2"
+  [(set_attr "type" "imul")
+   (set_attr "mode" "SI")]
+)
+
+(define_insn "*th_msubhisi4"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+	(minus:SI (match_operand:SI 3 "register_operand" " 0")
+		  (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" " r"))
+			   (sign_extend:SI (match_operand:HI 2 "register_operand" " r")))))]
+  "TARGET_XTHEADMAC"
+  "th.mulsh\\t%0,%1,%2"
+  [(set_attr "type" "imul")
+   (set_attr "mode" "SI")]
+)
+
+(define_insn "*th_sextw_msubhisi4"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+	(sign_extend:DI
+	  (minus:SI (match_operand:SI 3 "register_operand" " 0")
+		    (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" " r"))
+			     (sign_extend:SI (match_operand:HI 2 "register_operand" " r"))))))]
+  "TARGET_XTHEADMAC && TARGET_64BIT"
+  "th.mulsh\\t%0,%1,%2"
+  [(set_attr "type" "imul")
+   (set_attr "mode" "SI")]
+)
+
diff --git a/gcc/testsuite/gcc.target/riscv/thead-mula-1.c b/gcc/testsuite/gcc.target/riscv/thead-mula-1.c
new file mode 100644
index 00000000000..446bbdd98a1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/thead-mula-1.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=rv64gc_xtheadmac -mabi=lp64" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+long f_mula(long a, long b, long c)
+{
+  return a + b * c;
+}
+
+long f_muls(long a, long b, long c)
+{
+  return a - b * c;
+}
+
+int f_mulaw(int a, int b, int c)
+{
+  return a + b * c;
+}
+
+int f_mulsw(int a, int b, int c)
+{
+  return a - b * c;
+}
+
+long f_mulah(int a, unsigned short b, unsigned short c)
+{
+  return a + (int)(short)b * (int)(short)c;
+}
+
+long f_mulsh(int a, unsigned short b, unsigned short c)
+{
+  return a - (int)(short)b * (int)(short)c;
+}
+
+/* { dg-final { scan-assembler-times "th.mula\t" 1 } } */
+/* { dg-final { scan-assembler-times "th.muls\t" 1 } } */
+/* { dg-final { scan-assembler-times "th.mulaw\t" 1 } } */
+/* { dg-final { scan-assembler-times "th.mulsw\t" 1 } } */
+/* { dg-final { scan-assembler-times "th.mulah\t" 1 } } */
+/* { dg-final { scan-assembler-times "th.mulsh\t" 1 } } */
diff --git a/gcc/testsuite/gcc.target/riscv/thead-mula-2.c b/gcc/testsuite/gcc.target/riscv/thead-mula-2.c
new file mode 100644
index 00000000000..87145669573
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/thead-mula-2.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=rv32gc_xtheadmac -mabi=ilp32" } */
+/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */
+
+long f_mula(long a, long b, long c)
+{
+  return a + b * c;
+}
+
+long f_muls(long a, long b, long c)
+{
+  return a - b * c;
+}
+
+long f_mulah(int a, unsigned short b, unsigned short c)
+{
+  return a + (int)(short)b * (int)(short)c;
+}
+
+long f_mulsh(int a, unsigned short b, unsigned short c)
+{
+  return a - (int)(short)b * (int)(short)c;
+}
+
+/* { dg-final { scan-assembler-times "th.mula\t" 1 } } */
+/* { dg-final { scan-assembler-times "th.muls\t" 1 } } */
+/* { dg-final { scan-assembler-times "th.mulah\t" 1 } } */
+/* { dg-final { scan-assembler-times "th.mulsh\t" 1 } } */
-- 
2.38.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 7/7] riscv: Add basic extension support for XTheadFmv and XTheadInt
  2022-11-13 21:46 [PATCH 0/7] Add XThead* support Christoph Muellner
                   ` (5 preceding siblings ...)
  2022-11-13 21:46 ` [PATCH 6/7] riscv: thead: Add support for XTheadMac " Christoph Muellner
@ 2022-11-13 21:46 ` Christoph Muellner
  2022-11-18  4:43   ` cooper.qu
                     ` (2 more replies)
  6 siblings, 3 replies; 20+ messages in thread
From: Christoph Muellner @ 2022-11-13 21:46 UTC (permalink / raw)
  To: gcc-patches, Kito Cheng, Jim Wilson, Palmer Dabbelt,
	Andrew Waterman, Philipp Tomsich, Cooper Qu, Lifang Xia,
	Yunhai Shang, Zhiwei Liu
  Cc: Christoph Müllner

From: Christoph Müllner <christoph.muellner@vrull.eu>

This patch add basic support for the XTheadFmv and XTheadInt
ISA extension. As both extensions only contain instruction,
which are not supposed to be emitted by the compiler, the support
only covers awareness of the extension name in the march string
and the definition of a feature test macro.

gcc/ChangeLog:

	* common/config/riscv/riscv-common.cc: Add xtheadfmv and
	  xtheadint.
	* config/riscv/riscv-opts.h (MASK_XTHEADMAC): New.
	(MASK_XTHEADFMV): New.
	(TARGET_XTHEADFMV): New.
	(MASK_XTHEADINT): New.
	(TARGET_XTHEADINT): New.
	(MASK_XTHEADMEMIDX): New.
	(MASK_XTHEADSYNC): New.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/xtheadfmv.c: New test.
	* gcc.target/riscv/xtheadint.c: New test.

Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
---
 gcc/common/config/riscv/riscv-common.cc    |  4 ++++
 gcc/config/riscv/riscv-opts.h              | 10 +++++++---
 gcc/testsuite/gcc.target/riscv/xtheadfmv.c | 14 ++++++++++++++
 gcc/testsuite/gcc.target/riscv/xtheadint.c | 14 ++++++++++++++
 4 files changed, 39 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadfmv.c
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadint.c

diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc
index 8e1449d3543..b3e6732dddd 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -228,6 +228,8 @@ static const struct riscv_ext_version riscv_ext_version_table[] =
   {"xtheadcmo", ISA_SPEC_CLASS_NONE, 1, 0},
   {"xtheadcondmov", ISA_SPEC_CLASS_NONE, 1, 0},
   {"xtheadfmemidx", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadfmv", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"xtheadint", ISA_SPEC_CLASS_NONE, 1, 0},
   {"xtheadmac", ISA_SPEC_CLASS_NONE, 1, 0},
   {"xtheadmemidx", ISA_SPEC_CLASS_NONE, 1, 0},
   {"xtheadsync", ISA_SPEC_CLASS_NONE, 1, 0},
@@ -1263,6 +1265,8 @@ static const riscv_ext_flag_table_t riscv_ext_flag_table[] =
   {"xtheadcmo",     &gcc_options::x_riscv_xthead_subext, MASK_XTHEADCMO},
   {"xtheadcondmov", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADCONDMOV},
   {"xtheadfmemidx", &gcc_options::x_riscv_xthead_subext, MASK_XTHEADFMEMIDX},
+  {"xtheadfmv",     &gcc_options::x_riscv_xthead_subext, MASK_XTHEADFMV},
+  {"xtheadint",     &gcc_options::x_riscv_xthead_subext, MASK_XTHEADINT},
   {"xtheadmac",     &gcc_options::x_riscv_xthead_subext, MASK_XTHEADMAC},
   {"xtheadmemidx",  &gcc_options::x_riscv_xthead_subext, MASK_XTHEADMEMIDX},
   {"xtheadsync",    &gcc_options::x_riscv_xthead_subext, MASK_XTHEADSYNC},
diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
index 18daac40dbd..c1868dcf284 100644
--- a/gcc/config/riscv/riscv-opts.h
+++ b/gcc/config/riscv/riscv-opts.h
@@ -201,11 +201,15 @@ enum stack_protector_guard {
 #define TARGET_XTHEADCONDMOV	((riscv_xthead_subext & MASK_XTHEADCONDMOV) != 0)
 #define MASK_XTHEADFMEMIDX	(1 << 5)
 #define TARGET_XTHEADFMEMIDX	((riscv_xthead_subext & MASK_XTHEADFMEMIDX) != 0)
-#define MASK_XTHEADMAC		(1 << 6)
+#define MASK_XTHEADFMV		(1 << 6)
+#define TARGET_XTHEADFMV	((riscv_xthead_subext & MASK_XTHEADFMV) != 0)
+#define MASK_XTHEADINT		(1 << 7)
+#define TARGET_XTHEADINT	((riscv_xthead_subext & MASK_XTHEADINT) != 0)
+#define MASK_XTHEADMAC		(1 << 8)
 #define TARGET_XTHEADMAC	((riscv_xthead_subext & MASK_XTHEADMAC) != 0)
-#define MASK_XTHEADMEMIDX	(1 << 7)
+#define MASK_XTHEADMEMIDX	(1 << 9)
 #define TARGET_XTHEADMEMIDX	((riscv_xthead_subext & MASK_XTHEADMEMIDX) != 0)
-#define MASK_XTHEADSYNC		(1 << 8)
+#define MASK_XTHEADSYNC		(1 << 10)
 #define TARGET_XTHEADSYNC	((riscv_xthead_subext & MASK_XTHEADSYNC) != 0)
 
 #endif /* ! GCC_RISCV_OPTS_H */
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadfmv.c b/gcc/testsuite/gcc.target/riscv/xtheadfmv.c
new file mode 100644
index 00000000000..e97e8f461f6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadfmv.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_xtheadfmv" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_xtheadfmv" { target { rv64 } } } */
+
+#ifndef __riscv_xtheadfmv
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+  return a;
+}
+
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadint.c b/gcc/testsuite/gcc.target/riscv/xtheadint.c
new file mode 100644
index 00000000000..ee6989a380e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadint.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_xtheadint" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_xtheadint" { target { rv64 } } } */
+
+#ifndef __riscv_xtheadint
+#error Feature macro not defined
+#endif
+
+int
+foo (int a)
+{
+  return a;
+}
+
-- 
2.38.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 5/7] riscv: thead: Add support for XTheadBb ISA extension
  2022-11-13 21:46 ` [PATCH 5/7] riscv: thead: Add support for XTheadBb ISA extension Christoph Muellner
@ 2022-11-18  4:21   ` cooper.qu
  0 siblings, 0 replies; 20+ messages in thread
From: cooper.qu @ 2022-11-18  4:21 UTC (permalink / raw)
  To: Christoph Muellner; +Cc: gcc-patches

On Sun, Nov 13, 2022 at 10:46:34PM +0100, Christoph Muellner wrote:
> +(define_expand "extv<mode>"
> +  [(set (match_operand:GPR 0 "register_operand" "=r")
> +	(sign_extract:GPR (match_operand:GPR 1 "register_operand" "r")
> +			 (match_operand 2 "const_int_operand")
> +			 (match_operand 3 "const_int_operand")))]
> +  "TARGET_XTHEADBB"
> +{
> +  if (TARGET_XTHEADBB
> +      && ((INTVAL (operands[2]) + INTVAL (operands[3]))
> +	  >= GET_MODE_BITSIZE (GET_MODE (operands[1])).to_constant ()))
> +    FAIL;
> +})
> +
> +(define_expand "extzv<mode>"
> +  [(set (match_operand:GPR 0 "register_operand" "=r")
> +	(zero_extract:GPR (match_operand:GPR 1 "register_operand" "r")
> +			 (match_operand 2 "const_int_operand")
> +			 (match_operand 3 "const_int_operand")))]
> +  "TARGET_XTHEADBB"
> +{
> +  if (TARGET_XTHEADBB
> +      && ((INTVAL (operands[2]) + INTVAL (operands[3]))
> +	  >= GET_MODE_BITSIZE (GET_MODE (operands[1])).to_constant ()))
> +    FAIL;
I doubt whether it is necessary to add this judgment here,
and other architectures seem to have not added it. But there's nothing wrong with adding
> +
> +(define_insn "*th_ext<mode>"
> +  [(set (match_operand:X 0 "register_operand" "=r")
> +	(sign_extract:X (match_operand:X 1 "register_operand" "r")
> +			(match_operand 2 "const_int_operand")
> +			(match_operand 3 "const_int_operand")))]
> +  "TARGET_XTHEADBB"
> +{
> +  operands[3] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
> +  return "th.ext\t%0,%1,%2,%3";
> +}
> +  [(set_attr "type" "bitmanip")])
> +
> +(define_insn "*th_extu<mode>"
> +  [(set (match_operand:X 0 "register_operand" "=r")
> +	(zero_extract:X (match_operand:X 1 "register_operand" "r")
> +			(match_operand 2 "const_int_operand")
> +			(match_operand 3 "const_int_operand")))]
> +  "TARGET_XTHEADBB"
> +{
> +  operands[3] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]));
> +  return "th.extu\t%0,%1,%2,%3";
> +}
> +  [(set_attr "type" "bitmanip")])
> +

I think the operands[3] should be:
operands[3] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3])) - 1
Because the ext and extu extract the bits %2..%3, when size is 1, the 2%
equals to 3%.
And a small optimization can be done here, the extzv can generate c.andi
when the start bit is 0 and the size is less than 7.

> +/* { dg-final { scan-assembler-times "th.revw\t" 2 } } */
> +/* { dg-final { scan-assembler-times "th.rev\t" 2 } } */
> diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb-srri.c b/gcc/testsuite/gcc.target/riscv/xtheadbb-srri.c
> new file mode 100644
> index 00000000000..cd992ae3f0a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-srri.c
> @@ -0,0 +1,18 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv64gc_xtheadbb -mabi=lp64" } */
> +/* { dg-skip-if "" { *-*-* } { "-O0" "-g" } } */
> +
> +unsigned long foo1(unsigned long rs1)
> +{
> +    long shamt = __riscv_xlen - 11;
> +    return (rs1 << shamt) |
> +	   (rs1 >> ((__riscv_xlen - shamt) & (__riscv_xlen - 1)));
> +}
> +unsigned long foo2(unsigned long rs1)
> +{
> +    unsigned long shamt = __riscv_xlen - 11;
> +    return (rs1 >> shamt) |
> +	   (rs1 << ((__riscv_xlen - shamt) & (__riscv_xlen - 1)));
> +}
> +
> +/* { dg-final { scan-assembler-times "th.srri" 2 } } */

Why is there no testcase for ff1 here? It can be generated by the builtin function '__builtin_clzl'.


Thanks,
Cooper

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 7/7] riscv: Add basic extension support for XTheadFmv and XTheadInt
  2022-11-13 21:46 ` [PATCH 7/7] riscv: Add basic extension support for XTheadFmv and XTheadInt Christoph Muellner
@ 2022-11-18  4:43   ` cooper.qu
  2023-11-02  7:26   ` [RE] [7/7] " Jin Ma
  2023-11-07  3:04   ` [PATCH] riscv: thead: Add support for the XTheadInt ISA extension Jin Ma
  2 siblings, 0 replies; 20+ messages in thread
From: cooper.qu @ 2022-11-18  4:43 UTC (permalink / raw)
  To: Christoph Muellner; +Cc: gcc-patches

On Sun, Nov 13, 2022 at 10:46:36PM +0100, Christoph Muellner wrote:
> From: Christoph Müllner <christoph.muellner@vrull.eu>
> 
> This patch add basic support for the XTheadFmv and XTheadInt
> ISA extension. As both extensions only contain instruction,
> which are not supposed to be emitted by the compiler, the support
> only covers awareness of the extension name in the march string
> and the definition of a feature test macro.
>

I think the XTheadFmv can be emitted when the data is moved between
DImode and DFmode in rv32 target. The intructions are similar to the
move instructions of new standard extension "zfa".

Thanks,
Cooper

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2/7] riscv: riscv-cores.def: Add T-Head XuanTie C906
  2022-11-13 21:46 ` [PATCH 2/7] riscv: riscv-cores.def: Add T-Head XuanTie C906 Christoph Muellner
@ 2022-11-18  4:50   ` cooper.qu
  2022-11-18  4:58     ` Palmer Dabbelt
  0 siblings, 1 reply; 20+ messages in thread
From: cooper.qu @ 2022-11-18  4:50 UTC (permalink / raw)
  To: Christoph Muellner; +Cc: gcc-patches

On Sun, Nov 13, 2022 at 10:46:31PM +0100, Christoph Muellner wrote:
> From: Christoph Müllner <christoph.muellner@vrull.eu>
> 
> This adds T-Head's XuanTie C906 to the list of known cores as "thead-c906".
> The C906 is shipped for quite some time (it is the core of the Allwinner D1).
> Note, that the tuning struct for the C906 is already part of GCC (it is
> also name "thead-c906").
> 
> gcc/ChangeLog:
> 
> 	* config/riscv/riscv-cores.def (RISCV_CORE): Add "thead-c906".
> 
> gcc/testsuite/ChangeLog:
> 
> 	* gcc.target/riscv/mcpu-thead-c906.c: New test.
> 
> Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
> ---
>  gcc/config/riscv/riscv-cores.def               |  2 ++
>  .../gcc.target/riscv/mcpu-thead-c906.c         | 18 ++++++++++++++++++
>  2 files changed, 20 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c
> 
> diff --git a/gcc/config/riscv/riscv-cores.def b/gcc/config/riscv/riscv-cores.def
> index 31ad34682c5..648a010e09b 100644
> --- a/gcc/config/riscv/riscv-cores.def
> +++ b/gcc/config/riscv/riscv-cores.def
> @@ -73,4 +73,6 @@ RISCV_CORE("sifive-s76",      "rv64imafdc", "sifive-7-series")
>  RISCV_CORE("sifive-u54",      "rv64imafdc", "sifive-5-series")
>  RISCV_CORE("sifive-u74",      "rv64imafdc", "sifive-7-series")
>  
> +RISCV_CORE("thead-c906",      "rv64imafdc", "thead-c906")
> +

I think it makes more sense that thead-906 includes extended instructions by default.


Thanks,
Cooper

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 2/7] riscv: riscv-cores.def: Add T-Head XuanTie C906
  2022-11-18  4:50   ` cooper.qu
@ 2022-11-18  4:58     ` Palmer Dabbelt
  0 siblings, 0 replies; 20+ messages in thread
From: Palmer Dabbelt @ 2022-11-18  4:58 UTC (permalink / raw)
  To: gcc-patches; +Cc: christoph.muellner, gcc-patches

On Thu, 17 Nov 2022 20:50:19 PST (-0800), gcc-patches@gcc.gnu.org wrote:
> On Sun, Nov 13, 2022 at 10:46:31PM +0100, Christoph Muellner wrote:
>> From: Christoph Müllner <christoph.muellner@vrull.eu>
>>
>> This adds T-Head's XuanTie C906 to the list of known cores as "thead-c906".
>> The C906 is shipped for quite some time (it is the core of the Allwinner D1).
>> Note, that the tuning struct for the C906 is already part of GCC (it is
>> also name "thead-c906").
>>
>> gcc/ChangeLog:
>>
>> 	* config/riscv/riscv-cores.def (RISCV_CORE): Add "thead-c906".
>>
>> gcc/testsuite/ChangeLog:
>>
>> 	* gcc.target/riscv/mcpu-thead-c906.c: New test.
>>
>> Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
>> ---
>>  gcc/config/riscv/riscv-cores.def               |  2 ++
>>  .../gcc.target/riscv/mcpu-thead-c906.c         | 18 ++++++++++++++++++
>>  2 files changed, 20 insertions(+)
>>  create mode 100644 gcc/testsuite/gcc.target/riscv/mcpu-thead-c906.c
>>
>> diff --git a/gcc/config/riscv/riscv-cores.def b/gcc/config/riscv/riscv-cores.def
>> index 31ad34682c5..648a010e09b 100644
>> --- a/gcc/config/riscv/riscv-cores.def
>> +++ b/gcc/config/riscv/riscv-cores.def
>> @@ -73,4 +73,6 @@ RISCV_CORE("sifive-s76",      "rv64imafdc", "sifive-7-series")
>>  RISCV_CORE("sifive-u54",      "rv64imafdc", "sifive-5-series")
>>  RISCV_CORE("sifive-u74",      "rv64imafdc", "sifive-7-series")
>>
>> +RISCV_CORE("thead-c906",      "rv64imafdc", "thead-c906")
>> +
>
> I think it makes more sense that thead-906 includes extended instructions by default.

Seems reasonable to me, but Kito understands this stuff better than I 
do.  IMO `-mtune=thead-c906` should leave the ISA targets alone and just 
set the tune info, and `-mcpu=thead-c906` should do that and also set 
the ISA to whatever's implemented on that core.

That said, I was playing around with some B-extension multilib stuff 
recently and am pretty sure this stuff is all a bit broken.  Maybe we 
should punt on enabling all these extensions for `-mcpu` until we have 
that sorted out?  IMO we're at the point where having ISA-dependent 
multilib paths on Linux makes sense, but that risks throwing another 
wrench into distro folks.

Maybe it doesn't matter, though?  IIUC distros aren't shipping multilib 
right now so the bugs won't manifest for users.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [RE] [7/7] riscv: Add basic extension support for XTheadFmv and XTheadInt
  2022-11-13 21:46 ` [PATCH 7/7] riscv: Add basic extension support for XTheadFmv and XTheadInt Christoph Muellner
  2022-11-18  4:43   ` cooper.qu
@ 2023-11-02  7:26   ` Jin Ma
  2023-11-02  7:42     ` Christoph Müllner
  2023-11-07  3:04   ` [PATCH] riscv: thead: Add support for the XTheadInt ISA extension Jin Ma
  2 siblings, 1 reply; 20+ messages in thread
From: Jin Ma @ 2023-11-02  7:26 UTC (permalink / raw)
  To: gcc-patches, christoph.muellner; +Cc: jinma.contrib, Jin Ma

Hi, I see that XTheadInt is not implemented in the compiler. Is there any plan here?
If there is no patch for it, can I try to implement it with you?

Thanks

Jin

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [RE] [7/7] riscv: Add basic extension support for XTheadFmv and XTheadInt
  2023-11-02  7:26   ` [RE] [7/7] " Jin Ma
@ 2023-11-02  7:42     ` Christoph Müllner
  0 siblings, 0 replies; 20+ messages in thread
From: Christoph Müllner @ 2023-11-02  7:42 UTC (permalink / raw)
  To: Jin Ma; +Cc: GCC Patches, jinma.contrib

[-- Attachment #1: Type: text/plain, Size: 376 bytes --]

On Thu, Nov 2, 2023, 08:32 Jin Ma <jinma@linux.alibaba.com> wrote:

> Hi, I see that XTheadInt is not implemented in the compiler. Is there any
> plan here?
> If there is no patch for it, can I try to implement it with you?
>

Yes, sounds good.
Let me know if you have any questions.
We don't have any plans to work on this at the moment.

BR
Christoph




> Thanks
>
> Jin
>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH] riscv: thead: Add support for the XTheadInt ISA extension
  2022-11-13 21:46 ` [PATCH 7/7] riscv: Add basic extension support for XTheadFmv and XTheadInt Christoph Muellner
  2022-11-18  4:43   ` cooper.qu
  2023-11-02  7:26   ` [RE] [7/7] " Jin Ma
@ 2023-11-07  3:04   ` Jin Ma
  2023-11-10 15:05     ` Christoph Müllner
  2023-11-17  7:33     ` [PATCH v2] RISC-V: T-HEAD: " Jin Ma
  2 siblings, 2 replies; 20+ messages in thread
From: Jin Ma @ 2023-11-07  3:04 UTC (permalink / raw)
  To: gcc-patches, christoph.muellner; +Cc: jinma.contrib, Jin Ma

The XTheadInt ISA extension provides acceleration interruption
instructions as defined in T-Head-specific:

* th.ipush
* th.ipop

gcc/ChangeLog:

	* config/riscv/riscv-protos.h (th_int_get_mask): New prototype.
	(th_int_get_save_adjustment): Likewise.
	(th_int_adjust_cfi_prologue): Likewise.
	* config/riscv/riscv.cc (TH_INT_INTERRUPT): New macro.
	(riscv_expand_prologue): Add the processing of XTheadInt.
	(riscv_expand_epilogue): Likewise.
	* config/riscv/riscv.md: New unspec.
	* config/riscv/thead.cc (BITSET_P): New macro.
	* config/riscv/thead.md (th_int_push): New pattern.
	(th_int_pop): New pattern.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/xtheadint-push-pop.c: New test.
---
 gcc/config/riscv/riscv-protos.h               |  3 +
 gcc/config/riscv/riscv.cc                     | 58 +++++++++++++-
 gcc/config/riscv/riscv.md                     |  4 +
 gcc/config/riscv/thead.cc                     | 78 +++++++++++++++++++
 gcc/config/riscv/thead.md                     | 67 ++++++++++++++++
 .../gcc.target/riscv/xtheadint-push-pop.c     | 36 +++++++++
 6 files changed, 245 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadint-push-pop.c

diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 85d4f6ed9ea..05d1fc2b3a0 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -627,6 +627,9 @@ extern void th_mempair_prepare_save_restore_operands (rtx[4], bool,
 						      int, HOST_WIDE_INT,
 						      int, HOST_WIDE_INT);
 extern void th_mempair_save_restore_regs (rtx[4], bool, machine_mode);
+extern unsigned int th_int_get_mask(unsigned int);
+extern unsigned int th_int_get_save_adjustment();
+extern rtx th_int_adjust_cfi_prologue (unsigned int);
 #ifdef RTX_CODE
 extern const char*
 th_mempair_output_move (rtx[4], bool, machine_mode, RTX_CODE);
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 08ff05dcc3f..c623101b05e 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -101,6 +101,16 @@ along with GCC; see the file COPYING3.  If not see
 /* True the mode switching has static frm, or false.  */
 #define STATIC_FRM_P(c) ((c)->machine->mode_sw_info.static_frm_p)
 
+/* True if we can use the instructions in the XTheadInt extension
+   to handle interrupts, or false.  */
+#define TH_INT_INTERRUPT(c)					\
+  (TARGET_XTHEADINT						\
+   /* The XTheadInt extension only supports rv32.  */		\
+   && !TARGET_64BIT						\
+   && (c)->machine->interrupt_handler_p				\
+   /* This instruction can be executed in M-mode only.*/	\
+   && (c)->machine->interrupt_mode == MACHINE_MODE)
+
 /* Information about a function's frame layout.  */
 struct GTY(())  riscv_frame_info {
   /* The size of the frame in bytes.  */
@@ -6703,6 +6713,7 @@ riscv_expand_prologue (void)
   unsigned fmask = frame->fmask;
   int spimm, multi_push_additional, stack_adj;
   rtx insn, dwarf = NULL_RTX;
+  unsigned th_int_mask = 0;
 
   if (flag_stack_usage_info)
     current_function_static_stack_size = constant_lower_bound (remaining_size);
@@ -6771,6 +6782,28 @@ riscv_expand_prologue (void)
       REG_NOTES (insn) = dwarf;
     }
 
+  th_int_mask = th_int_get_mask(frame->mask);
+  if (th_int_mask && TH_INT_INTERRUPT (cfun))
+    {
+      frame->mask &= ~th_int_mask;
+
+      /* RISCV_PROLOGUE_TEMP may be used to handle some CSR for
+	 interrupts, such as fcsr. */
+      if ((TARGET_HARD_FLOAT  && frame->fmask)
+	  || (TARGET_ZFINX && frame->mask))
+	frame->mask |= (1 << RISCV_PROLOGUE_TEMP_REGNUM);
+
+      unsigned save_adjustment = th_int_get_save_adjustment ();
+      frame->gp_sp_offset -= save_adjustment;
+      remaining_size -= save_adjustment;
+
+      insn = emit_insn (gen_th_int_push ());
+
+      rtx dwarf = th_int_adjust_cfi_prologue (th_int_mask);
+      RTX_FRAME_RELATED_P (insn) = 1;
+      REG_NOTES (insn) = dwarf;
+    }
+
   /* Save the GP, FP registers.  */
   if ((frame->mask | frame->fmask) != 0)
     {
@@ -6999,6 +7032,7 @@ riscv_expand_epilogue (int style)
     = use_multi_pop ? frame->multi_push_adj_base + frame->multi_push_adj_addi
 		    : 0;
   rtx ra = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
+  unsigned th_int_mask = 0;
   rtx insn;
 
   /* We need to add memory barrier to prevent read from deallocated stack.  */
@@ -7161,12 +7195,32 @@ riscv_expand_epilogue (int style)
   else if (use_restore_libcall)
     frame->mask = 0; /* Temporarily fib that we need not restore GPRs.  */
 
+  th_int_mask = th_int_get_mask(frame->mask);
+  if (th_int_mask && TH_INT_INTERRUPT (cfun))
+    {
+      frame->mask &= ~th_int_mask;
+
+      /* RISCV_PROLOGUE_TEMP may be used to handle some CSR for
+	 interrupts, such as fcsr. */
+      if ((TARGET_HARD_FLOAT  && frame->fmask)
+	  || (TARGET_ZFINX && frame->mask))
+	frame->mask |= (1 << RISCV_PROLOGUE_TEMP_REGNUM);
+    }
+
   /* Restore the registers.  */
   riscv_for_each_saved_v_reg (step2, riscv_restore_reg, false);
   riscv_for_each_saved_reg (frame->total_size - step2 - libcall_size
 			      - multipop_size,
 			    riscv_restore_reg, true, style == EXCEPTION_RETURN);
 
+  if (th_int_mask && TH_INT_INTERRUPT (cfun))
+    {
+      frame->mask = mask; /* Undo the above fib.  */
+      unsigned save_adjustment = th_int_get_save_adjustment ();;
+      gcc_assert (step2.to_constant () >= save_adjustment);
+      step2 -= save_adjustment;
+    }
+
   if (use_restore_libcall)
     frame->mask = mask; /* Undo the above fib.  */
 
@@ -7229,7 +7283,9 @@ riscv_expand_epilogue (int style)
 
       gcc_assert (mode != UNKNOWN_MODE);
 
-      if (mode == MACHINE_MODE)
+      if (th_int_mask && TH_INT_INTERRUPT (cfun))
+	emit_jump_insn (gen_th_int_pop ());
+      else if (mode == MACHINE_MODE)
 	emit_jump_insn (gen_riscv_mret ());
       else if (mode == SUPERVISOR_MODE)
 	emit_jump_insn (gen_riscv_sret ());
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index ae2217d0907..d4147d08838 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -126,6 +126,10 @@ (define_c_enum "unspecv" [
   ;; XTheadFmv unspec
   UNSPEC_XTHEADFMV
   UNSPEC_XTHEADFMV_HW
+
+  ;; XTheadInt unspec
+  UNSPECV_XTHEADINT_PUSH
+  UNSPECV_XTHEADINT_POP
 ])
 
 (define_constants
diff --git a/gcc/config/riscv/thead.cc b/gcc/config/riscv/thead.cc
index a485fb1fba6..5b437c9a7a2 100644
--- a/gcc/config/riscv/thead.cc
+++ b/gcc/config/riscv/thead.cc
@@ -36,6 +36,9 @@
 #include "regs.h"
 #include "riscv-protos.h"
 
+/* True if bit BIT is set in VALUE.  */
+#define BITSET_P(VALUE, BIT) (((VALUE) & (1ULL << (BIT))) != 0)
+
 /* If MEM is in the form of "base+offset", extract the two parts
    of address and set to BASE and OFFSET, otherwise return false
    after clearing BASE and OFFSET.  */
@@ -945,3 +948,78 @@ th_print_operand_address (FILE *file, machine_mode mode, rtx x)
 
   gcc_unreachable ();
 }
+
+/* Number array of registers X1, X5-X7, X10-X17, X28-X31, to be
+   operated on by instruction th.ipush/th.ipop in XTheadInt.  */
+
+int th_int_regs[] ={
+  RETURN_ADDR_REGNUM,
+  T0_REGNUM, T1_REGNUM, T2_REGNUM,
+  A0_REGNUM, A1_REGNUM, A2_REGNUM, A3_REGNUM,
+  A4_REGNUM, A5_REGNUM, A6_REGNUM, A7_REGNUM,
+  T3_REGNUM, T4_REGNUM, T5_REGNUM, T6_REGNUM,
+};
+
+/* If MASK contains registers X1, X5-X7, X10-X17, X28-X31, then
+   return the mask composed of these registers, otherwise return
+   zero.  */
+
+unsigned int
+th_int_get_mask(unsigned int mask)
+{
+  unsigned int xtheadint_mask = 0;
+
+  if (!TARGET_XTHEADINT || TARGET_64BIT)
+    return 0;
+
+  for (unsigned int i = 0; i < ARRAY_SIZE (th_int_regs); i++)
+    {
+      if (!BITSET_P (mask, th_int_regs[i]))
+	return 0;
+
+      xtheadint_mask |= (1 << th_int_regs[i]);
+    }
+
+  return xtheadint_mask; /* Usually 0xf003fce2.  */
+}
+
+/* Returns the occupied frame needed to save registers X1, X5-X7,
+   X10-X17, X28-X31.*/
+
+unsigned int
+th_int_get_save_adjustment ()
+{
+  gcc_assert (TARGET_XTHEADINT && !TARGET_64BIT);
+  return ARRAY_SIZE (th_int_regs) * UNITS_PER_WORD;
+}
+
+rtx
+th_int_adjust_cfi_prologue (unsigned int mask)
+{
+  gcc_assert (TARGET_XTHEADINT && !TARGET_64BIT);
+
+  rtx dwarf = NULL_RTX;
+  rtx adjust_sp_rtx, reg, mem, insn;
+  int saved_size = ARRAY_SIZE (th_int_regs) * UNITS_PER_WORD;
+  int offset = saved_size;
+
+  for (int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
+    if (BITSET_P (mask, regno - GP_REG_FIRST))
+      {
+	offset -= UNITS_PER_WORD;
+	reg = gen_rtx_REG (SImode, regno);
+	mem = gen_frame_mem (SImode, plus_constant (Pmode,
+						    stack_pointer_rtx,
+						    offset));
+
+	insn = gen_rtx_SET (mem, reg);
+	dwarf = alloc_reg_note (REG_CFA_OFFSET, insn, dwarf);
+      }
+
+  /* Debug info for adjust sp.  */
+  adjust_sp_rtx = gen_rtx_SET (stack_pointer_rtx,
+	gen_rtx_PLUS (GET_MODE(stack_pointer_rtx), stack_pointer_rtx, GEN_INT (-saved_size)));
+  dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, adjust_sp_rtx, dwarf);
+
+  return dwarf;
+}
diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
index 2babfafb23c..4d6e16c0edc 100644
--- a/gcc/config/riscv/thead.md
+++ b/gcc/config/riscv/thead.md
@@ -210,6 +210,73 @@ (define_insn "th_fmv_x_hw"
    (set_attr "type" "fmove")
    (set_attr "mode" "DF")])
 
+;; XTheadInt
+
+(define_constants
+  [(T0_REGNUM	5)
+   (T1_REGNUM	6)
+   (T2_REGNUM	7)
+   (A0_REGNUM	10)
+   (A1_REGNUM	11)
+   (A2_REGNUM	12)
+   (A3_REGNUM	13)
+   (A4_REGNUM	14)
+   (A5_REGNUM	15)
+   (A6_REGNUM	16)
+   (A7_REGNUM	17)
+   (T3_REGNUM	28)
+   (T4_REGNUM	29)
+   (T5_REGNUM	30)
+   (T6_REGNUM	31)
+])
+
+(define_insn "th_int_push"
+  [(unspec_volatile [(const_int 0)] UNSPECV_XTHEADINT_PUSH)
+   (use (reg:SI RETURN_ADDR_REGNUM))
+   (use (reg:SI T0_REGNUM))
+   (use (reg:SI T1_REGNUM))
+   (use (reg:SI T2_REGNUM))
+   (use (reg:SI A0_REGNUM))
+   (use (reg:SI A1_REGNUM))
+   (use (reg:SI A2_REGNUM))
+   (use (reg:SI A3_REGNUM))
+   (use (reg:SI A4_REGNUM))
+   (use (reg:SI A5_REGNUM))
+   (use (reg:SI A6_REGNUM))
+   (use (reg:SI A7_REGNUM))
+   (use (reg:SI T3_REGNUM))
+   (use (reg:SI T4_REGNUM))
+   (use (reg:SI T5_REGNUM))
+   (use (reg:SI T6_REGNUM))]
+  "TARGET_XTHEADINT && !TARGET_64BIT"
+  "th.ipush"
+  [(set_attr "type"	"store")
+   (set_attr "mode"	"SI")])
+
+(define_insn "th_int_pop"
+  [(unspec_volatile [(const_int 0)] UNSPECV_XTHEADINT_POP)
+   (clobber (reg:SI RETURN_ADDR_REGNUM))
+   (clobber (reg:SI T0_REGNUM))
+   (clobber (reg:SI T1_REGNUM))
+   (clobber (reg:SI T2_REGNUM))
+   (clobber (reg:SI A0_REGNUM))
+   (clobber (reg:SI A1_REGNUM))
+   (clobber (reg:SI A2_REGNUM))
+   (clobber (reg:SI A3_REGNUM))
+   (clobber (reg:SI A4_REGNUM))
+   (clobber (reg:SI A5_REGNUM))
+   (clobber (reg:SI A6_REGNUM))
+   (clobber (reg:SI A7_REGNUM))
+   (clobber (reg:SI T3_REGNUM))
+   (clobber (reg:SI T4_REGNUM))
+   (clobber (reg:SI T5_REGNUM))
+   (clobber (reg:SI T6_REGNUM))
+   (return)]
+  "TARGET_XTHEADINT && !TARGET_64BIT"
+  "th.ipop"
+  [(set_attr "type"	"ret")
+   (set_attr "mode"	"SI")])
+
 ;; XTheadMac
 
 (define_insn "*th_mula<mode>"
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadint-push-pop.c b/gcc/testsuite/gcc.target/riscv/xtheadint-push-pop.c
new file mode 100644
index 00000000000..3383431aa30
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadint-push-pop.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_xtheadint -mabi=ilp32d" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_xtheadint -mabi=lp64d" { target { rv64 } } } */
+
+extern void f(void);
+
+__attribute__((interrupt))
+void func_default(void)
+{
+  f ();
+}
+
+__attribute__ ((interrupt ("machine")))
+void func_machine(void)
+{
+  f ();
+}
+
+/* { dg-final { scan-assembler-times {\tth\.ipush\n} 2 { target { rv32 } } } } */
+/* { dg-final { scan-assembler-times {\tth\.ipop\n} 2 { target { rv32 } } } } */
+
+
+__attribute__ ((interrupt ("user")))
+void func_usr(void)
+{
+  f ();
+}
+
+__attribute__ ((interrupt ("supervisor")))
+void func_supervisor(void)
+{
+  f ();
+}
+
+/* { dg-final { scan-assembler-not {\tth\.ipush\n} { target { rv64 } } } } */
+/* { dg-final { scan-assembler-not {\tth\.ipop\n} { target { rv64 } } } } */
\ No newline at end of file

base-commit: 2cca6ae615f3fb083d3a1e5e9dffcefd54fed990
-- 
2.17.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] riscv: thead: Add support for the XTheadInt ISA extension
  2023-11-07  3:04   ` [PATCH] riscv: thead: Add support for the XTheadInt ISA extension Jin Ma
@ 2023-11-10 15:05     ` Christoph Müllner
  2023-11-17  7:33     ` [PATCH v2] RISC-V: T-HEAD: " Jin Ma
  1 sibling, 0 replies; 20+ messages in thread
From: Christoph Müllner @ 2023-11-10 15:05 UTC (permalink / raw)
  To: Jin Ma; +Cc: gcc-patches, jinma.contrib

On Tue, Nov 7, 2023 at 4:04 AM Jin Ma <jinma@linux.alibaba.com> wrote:
>
> The XTheadInt ISA extension provides acceleration interruption
> instructions as defined in T-Head-specific:
>
> * th.ipush
> * th.ipop

Overall, it looks ok to me.
There are just a few small issues to clean up (see below).


>
> gcc/ChangeLog:
>
>         * config/riscv/riscv-protos.h (th_int_get_mask): New prototype.
>         (th_int_get_save_adjustment): Likewise.
>         (th_int_adjust_cfi_prologue): Likewise.
>         * config/riscv/riscv.cc (TH_INT_INTERRUPT): New macro.
>         (riscv_expand_prologue): Add the processing of XTheadInt.
>         (riscv_expand_epilogue): Likewise.
>         * config/riscv/riscv.md: New unspec.
>         * config/riscv/thead.cc (BITSET_P): New macro.
>         * config/riscv/thead.md (th_int_push): New pattern.
>         (th_int_pop): New pattern.
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.target/riscv/xtheadint-push-pop.c: New test.
> ---
>  gcc/config/riscv/riscv-protos.h               |  3 +
>  gcc/config/riscv/riscv.cc                     | 58 +++++++++++++-
>  gcc/config/riscv/riscv.md                     |  4 +
>  gcc/config/riscv/thead.cc                     | 78 +++++++++++++++++++
>  gcc/config/riscv/thead.md                     | 67 ++++++++++++++++
>  .../gcc.target/riscv/xtheadint-push-pop.c     | 36 +++++++++
>  6 files changed, 245 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadint-push-pop.c
>
> diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
> index 85d4f6ed9ea..05d1fc2b3a0 100644
> --- a/gcc/config/riscv/riscv-protos.h
> +++ b/gcc/config/riscv/riscv-protos.h
> @@ -627,6 +627,9 @@ extern void th_mempair_prepare_save_restore_operands (rtx[4], bool,
>                                                       int, HOST_WIDE_INT,
>                                                       int, HOST_WIDE_INT);
>  extern void th_mempair_save_restore_regs (rtx[4], bool, machine_mode);
> +extern unsigned int th_int_get_mask(unsigned int);

Space between function name and parenthesis.

> +extern unsigned int th_int_get_save_adjustment();

Space between function name and parenthesis.
An empty parameter list should be written as "(void)".

> +extern rtx th_int_adjust_cfi_prologue (unsigned int);
>  #ifdef RTX_CODE
>  extern const char*
>  th_mempair_output_move (rtx[4], bool, machine_mode, RTX_CODE);
> diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
> index 08ff05dcc3f..c623101b05e 100644
> --- a/gcc/config/riscv/riscv.cc
> +++ b/gcc/config/riscv/riscv.cc
> @@ -101,6 +101,16 @@ along with GCC; see the file COPYING3.  If not see
>  /* True the mode switching has static frm, or false.  */
>  #define STATIC_FRM_P(c) ((c)->machine->mode_sw_info.static_frm_p)
>
> +/* True if we can use the instructions in the XTheadInt extension
> +   to handle interrupts, or false.  */
> +#define TH_INT_INTERRUPT(c)                                    \
> +  (TARGET_XTHEADINT                                            \
> +   /* The XTheadInt extension only supports rv32.  */          \
> +   && !TARGET_64BIT                                            \
> +   && (c)->machine->interrupt_handler_p                                \
> +   /* This instruction can be executed in M-mode only.*/       \

Dot, space, space, end of comment.

Maybe better:
/* The XTheadInt instructions can only be executed in M-mode.  */

> +   && (c)->machine->interrupt_mode == MACHINE_MODE)
> +
>  /* Information about a function's frame layout.  */
>  struct GTY(())  riscv_frame_info {
>    /* The size of the frame in bytes.  */
> @@ -6703,6 +6713,7 @@ riscv_expand_prologue (void)
>    unsigned fmask = frame->fmask;
>    int spimm, multi_push_additional, stack_adj;
>    rtx insn, dwarf = NULL_RTX;
> +  unsigned th_int_mask = 0;
>
>    if (flag_stack_usage_info)
>      current_function_static_stack_size = constant_lower_bound (remaining_size);
> @@ -6771,6 +6782,28 @@ riscv_expand_prologue (void)
>        REG_NOTES (insn) = dwarf;
>      }
>
> +  th_int_mask = th_int_get_mask(frame->mask);

There should be exactly one space between function name and parenthesis.

> +  if (th_int_mask && TH_INT_INTERRUPT (cfun))
> +    {
> +      frame->mask &= ~th_int_mask;
> +
> +      /* RISCV_PROLOGUE_TEMP may be used to handle some CSR for
> +        interrupts, such as fcsr. */

Dot, space, space, end of comment.

> +      if ((TARGET_HARD_FLOAT  && frame->fmask)
> +         || (TARGET_ZFINX && frame->mask))
> +       frame->mask |= (1 << RISCV_PROLOGUE_TEMP_REGNUM);
> +
> +      unsigned save_adjustment = th_int_get_save_adjustment ();
> +      frame->gp_sp_offset -= save_adjustment;
> +      remaining_size -= save_adjustment;
> +
> +      insn = emit_insn (gen_th_int_push ());
> +
> +      rtx dwarf = th_int_adjust_cfi_prologue (th_int_mask);
> +      RTX_FRAME_RELATED_P (insn) = 1;
> +      REG_NOTES (insn) = dwarf;
> +    }
> +
>    /* Save the GP, FP registers.  */
>    if ((frame->mask | frame->fmask) != 0)
>      {
> @@ -6999,6 +7032,7 @@ riscv_expand_epilogue (int style)
>      = use_multi_pop ? frame->multi_push_adj_base + frame->multi_push_adj_addi
>                     : 0;
>    rtx ra = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
> +  unsigned th_int_mask = 0;
>    rtx insn;
>
>    /* We need to add memory barrier to prevent read from deallocated stack.  */
> @@ -7161,12 +7195,32 @@ riscv_expand_epilogue (int style)
>    else if (use_restore_libcall)
>      frame->mask = 0; /* Temporarily fib that we need not restore GPRs.  */
>
> +  th_int_mask = th_int_get_mask(frame->mask);

There should be exactly one space between function name and parenthesis.

> +  if (th_int_mask && TH_INT_INTERRUPT (cfun))
> +    {
> +      frame->mask &= ~th_int_mask;
> +
> +      /* RISCV_PROLOGUE_TEMP may be used to handle some CSR for
> +        interrupts, such as fcsr. */

Dot, space, space, end of comment.

> +      if ((TARGET_HARD_FLOAT  && frame->fmask)
> +         || (TARGET_ZFINX && frame->mask))
> +       frame->mask |= (1 << RISCV_PROLOGUE_TEMP_REGNUM);
> +    }
> +
>    /* Restore the registers.  */
>    riscv_for_each_saved_v_reg (step2, riscv_restore_reg, false);
>    riscv_for_each_saved_reg (frame->total_size - step2 - libcall_size
>                               - multipop_size,
>                             riscv_restore_reg, true, style == EXCEPTION_RETURN);
>
> +  if (th_int_mask && TH_INT_INTERRUPT (cfun))
> +    {
> +      frame->mask = mask; /* Undo the above fib.  */
> +      unsigned save_adjustment = th_int_get_save_adjustment ();;

Double semi-colon.

> +      gcc_assert (step2.to_constant () >= save_adjustment);
> +      step2 -= save_adjustment;
> +    }
> +
>    if (use_restore_libcall)
>      frame->mask = mask; /* Undo the above fib.  */
>
> @@ -7229,7 +7283,9 @@ riscv_expand_epilogue (int style)
>
>        gcc_assert (mode != UNKNOWN_MODE);
>
> -      if (mode == MACHINE_MODE)
> +      if (th_int_mask && TH_INT_INTERRUPT (cfun))
> +       emit_jump_insn (gen_th_int_pop ());
> +      else if (mode == MACHINE_MODE)
>         emit_jump_insn (gen_riscv_mret ());
>        else if (mode == SUPERVISOR_MODE)
>         emit_jump_insn (gen_riscv_sret ());
> diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
> index ae2217d0907..d4147d08838 100644
> --- a/gcc/config/riscv/riscv.md
> +++ b/gcc/config/riscv/riscv.md
> @@ -126,6 +126,10 @@ (define_c_enum "unspecv" [
>    ;; XTheadFmv unspec
>    UNSPEC_XTHEADFMV
>    UNSPEC_XTHEADFMV_HW
> +
> +  ;; XTheadInt unspec
> +  UNSPECV_XTHEADINT_PUSH
> +  UNSPECV_XTHEADINT_POP
>  ])
>
>  (define_constants
> diff --git a/gcc/config/riscv/thead.cc b/gcc/config/riscv/thead.cc
> index a485fb1fba6..5b437c9a7a2 100644
> --- a/gcc/config/riscv/thead.cc
> +++ b/gcc/config/riscv/thead.cc
> @@ -36,6 +36,9 @@
>  #include "regs.h"
>  #include "riscv-protos.h"
>
> +/* True if bit BIT is set in VALUE.  */
> +#define BITSET_P(VALUE, BIT) (((VALUE) & (1ULL << (BIT))) != 0)
> +

This is copied from riscv.cc.
Let's better move it to riscv.h instead of duplicating it.

>  /* If MEM is in the form of "base+offset", extract the two parts
>     of address and set to BASE and OFFSET, otherwise return false
>     after clearing BASE and OFFSET.  */
> @@ -945,3 +948,78 @@ th_print_operand_address (FILE *file, machine_mode mode, rtx x)
>
>    gcc_unreachable ();
>  }
> +
> +/* Number array of registers X1, X5-X7, X10-X17, X28-X31, to be
> +   operated on by instruction th.ipush/th.ipop in XTheadInt.  */
> +
> +int th_int_regs[] ={
> +  RETURN_ADDR_REGNUM,
> +  T0_REGNUM, T1_REGNUM, T2_REGNUM,
> +  A0_REGNUM, A1_REGNUM, A2_REGNUM, A3_REGNUM,
> +  A4_REGNUM, A5_REGNUM, A6_REGNUM, A7_REGNUM,
> +  T3_REGNUM, T4_REGNUM, T5_REGNUM, T6_REGNUM,
> +};
> +
> +/* If MASK contains registers X1, X5-X7, X10-X17, X28-X31, then
> +   return the mask composed of these registers, otherwise return
> +   zero.  */
> +
> +unsigned int
> +th_int_get_mask(unsigned int mask)

There should be exactly one space between function name and parenthesis.

> +{
> +  unsigned int xtheadint_mask = 0;
> +
> +  if (!TARGET_XTHEADINT || TARGET_64BIT)
> +    return 0;
> +
> +  for (unsigned int i = 0; i < ARRAY_SIZE (th_int_regs); i++)
> +    {
> +      if (!BITSET_P (mask, th_int_regs[i]))
> +       return 0;
> +
> +      xtheadint_mask |= (1 << th_int_regs[i]);
> +    }
> +
> +  return xtheadint_mask; /* Usually 0xf003fce2.  */
> +}
> +
> +/* Returns the occupied frame needed to save registers X1, X5-X7,
> +   X10-X17, X28-X31.*/

Dot, space, space, end of comment.

> +
> +unsigned int
> +th_int_get_save_adjustment ()

"()" -> "(void)"

> +{
> +  gcc_assert (TARGET_XTHEADINT && !TARGET_64BIT);
> +  return ARRAY_SIZE (th_int_regs) * UNITS_PER_WORD;
> +}
> +
> +rtx
> +th_int_adjust_cfi_prologue (unsigned int mask)
> +{
> +  gcc_assert (TARGET_XTHEADINT && !TARGET_64BIT);
> +
> +  rtx dwarf = NULL_RTX;
> +  rtx adjust_sp_rtx, reg, mem, insn;
> +  int saved_size = ARRAY_SIZE (th_int_regs) * UNITS_PER_WORD;
> +  int offset = saved_size;
> +
> +  for (int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
> +    if (BITSET_P (mask, regno - GP_REG_FIRST))
> +      {
> +       offset -= UNITS_PER_WORD;
> +       reg = gen_rtx_REG (SImode, regno);
> +       mem = gen_frame_mem (SImode, plus_constant (Pmode,
> +                                                   stack_pointer_rtx,
> +                                                   offset));
> +
> +       insn = gen_rtx_SET (mem, reg);
> +       dwarf = alloc_reg_note (REG_CFA_OFFSET, insn, dwarf);
> +      }
> +
> +  /* Debug info for adjust sp.  */
> +  adjust_sp_rtx = gen_rtx_SET (stack_pointer_rtx,
> +       gen_rtx_PLUS (GET_MODE(stack_pointer_rtx), stack_pointer_rtx, GEN_INT (-saved_size)));

There should be exactly one space between function name and parenthesis.

> +  dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, adjust_sp_rtx, dwarf);
> +
> +  return dwarf;
> +}
> diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
> index 2babfafb23c..4d6e16c0edc 100644
> --- a/gcc/config/riscv/thead.md
> +++ b/gcc/config/riscv/thead.md
> @@ -210,6 +210,73 @@ (define_insn "th_fmv_x_hw"
>     (set_attr "type" "fmove")
>     (set_attr "mode" "DF")])
>
> +;; XTheadInt
> +
> +(define_constants
> +  [(T0_REGNUM  5)
> +   (T1_REGNUM  6)
> +   (T2_REGNUM  7)
> +   (A0_REGNUM  10)
> +   (A1_REGNUM  11)
> +   (A2_REGNUM  12)
> +   (A3_REGNUM  13)
> +   (A4_REGNUM  14)
> +   (A5_REGNUM  15)
> +   (A6_REGNUM  16)
> +   (A7_REGNUM  17)
> +   (T3_REGNUM  28)
> +   (T4_REGNUM  29)
> +   (T5_REGNUM  30)
> +   (T6_REGNUM  31)
> +])
> +
> +(define_insn "th_int_push"
> +  [(unspec_volatile [(const_int 0)] UNSPECV_XTHEADINT_PUSH)
> +   (use (reg:SI RETURN_ADDR_REGNUM))
> +   (use (reg:SI T0_REGNUM))
> +   (use (reg:SI T1_REGNUM))
> +   (use (reg:SI T2_REGNUM))
> +   (use (reg:SI A0_REGNUM))
> +   (use (reg:SI A1_REGNUM))
> +   (use (reg:SI A2_REGNUM))
> +   (use (reg:SI A3_REGNUM))
> +   (use (reg:SI A4_REGNUM))
> +   (use (reg:SI A5_REGNUM))
> +   (use (reg:SI A6_REGNUM))
> +   (use (reg:SI A7_REGNUM))
> +   (use (reg:SI T3_REGNUM))
> +   (use (reg:SI T4_REGNUM))
> +   (use (reg:SI T5_REGNUM))
> +   (use (reg:SI T6_REGNUM))]
> +  "TARGET_XTHEADINT && !TARGET_64BIT"
> +  "th.ipush"
> +  [(set_attr "type"    "store")
> +   (set_attr "mode"    "SI")])
> +
> +(define_insn "th_int_pop"
> +  [(unspec_volatile [(const_int 0)] UNSPECV_XTHEADINT_POP)
> +   (clobber (reg:SI RETURN_ADDR_REGNUM))
> +   (clobber (reg:SI T0_REGNUM))
> +   (clobber (reg:SI T1_REGNUM))
> +   (clobber (reg:SI T2_REGNUM))
> +   (clobber (reg:SI A0_REGNUM))
> +   (clobber (reg:SI A1_REGNUM))
> +   (clobber (reg:SI A2_REGNUM))
> +   (clobber (reg:SI A3_REGNUM))
> +   (clobber (reg:SI A4_REGNUM))
> +   (clobber (reg:SI A5_REGNUM))
> +   (clobber (reg:SI A6_REGNUM))
> +   (clobber (reg:SI A7_REGNUM))
> +   (clobber (reg:SI T3_REGNUM))
> +   (clobber (reg:SI T4_REGNUM))
> +   (clobber (reg:SI T5_REGNUM))
> +   (clobber (reg:SI T6_REGNUM))
> +   (return)]
> +  "TARGET_XTHEADINT && !TARGET_64BIT"
> +  "th.ipop"
> +  [(set_attr "type"    "ret")
> +   (set_attr "mode"    "SI")])
> +
>  ;; XTheadMac
>
>  (define_insn "*th_mula<mode>"
> diff --git a/gcc/testsuite/gcc.target/riscv/xtheadint-push-pop.c b/gcc/testsuite/gcc.target/riscv/xtheadint-push-pop.c
> new file mode 100644
> index 00000000000..3383431aa30
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/riscv/xtheadint-push-pop.c
> @@ -0,0 +1,36 @@
> +/* { dg-do compile } */
> +/* { dg-options "-march=rv32gc_xtheadint -mabi=ilp32d" { target { rv32 } } } */
> +/* { dg-options "-march=rv64gc_xtheadint -mabi=lp64d" { target { rv64 } } } */
> +
> +extern void f(void);
> +
> +__attribute__((interrupt))
> +void func_default(void)

There should be exactly one space between function name and parenthesis.

> +{
> +  f ();
> +}
> +
> +__attribute__ ((interrupt ("machine")))
> +void func_machine(void)

There should be exactly one space between function name and parenthesis.

> +{
> +  f ();
> +}
> +
> +/* { dg-final { scan-assembler-times {\tth\.ipush\n} 2 { target { rv32 } } } } */
> +/* { dg-final { scan-assembler-times {\tth\.ipop\n} 2 { target { rv32 } } } } */
> +
> +
> +__attribute__ ((interrupt ("user")))
> +void func_usr(void)
> +{
> +  f ();
> +}
> +
> +__attribute__ ((interrupt ("supervisor")))
> +void func_supervisor(void)
> +{
> +  f ();
> +}
> +
> +/* { dg-final { scan-assembler-not {\tth\.ipush\n} { target { rv64 } } } } */
> +/* { dg-final { scan-assembler-not {\tth\.ipop\n} { target { rv64 } } } } */
> \ No newline at end of file
>
> base-commit: 2cca6ae615f3fb083d3a1e5e9dffcefd54fed990
> --
> 2.17.1
>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH v2] RISC-V: T-HEAD: Add support for the XTheadInt ISA extension
  2023-11-07  3:04   ` [PATCH] riscv: thead: Add support for the XTheadInt ISA extension Jin Ma
  2023-11-10 15:05     ` Christoph Müllner
@ 2023-11-17  7:33     ` Jin Ma
  2024-01-09  9:35       ` Jin Ma
  2024-01-09 17:59       ` [PATCH " Jeff Law
  1 sibling, 2 replies; 20+ messages in thread
From: Jin Ma @ 2023-11-17  7:33 UTC (permalink / raw)
  To: gcc-patches; +Cc: kito.cheng, christoph.muellner, jinma.contrib, Jin Ma

The XTheadInt ISA extension provides acceleration interruption
instructions as defined in T-Head-specific:
* th.ipush
* th.ipop

Ref:
https://github.com/T-head-Semi/thead-extension-spec/releases/download/2.3.0/xthead-2023-11-10-2.3.0.pdf

gcc/ChangeLog:

	* config/riscv/riscv-protos.h (th_int_get_mask): New prototype.
	(th_int_get_save_adjustment): Likewise.
	(th_int_adjust_cfi_prologue): Likewise.
	* config/riscv/riscv.cc (TH_INT_INTERRUPT): New macro.
	(riscv_expand_prologue): Add the processing of XTheadInt.
	(riscv_expand_epilogue): Likewise.
	* config/riscv/riscv.md: New unspec.
	* config/riscv/thead.cc (BITSET_P): New macro.
	* config/riscv/thead.md (th_int_push): New pattern.
	(th_int_pop): New pattern.

gcc/testsuite/ChangeLog:

	* gcc.target/riscv/xtheadint-push-pop.c: New test.
---
 gcc/config/riscv/riscv-protos.h               |  3 +
 gcc/config/riscv/riscv.cc                     | 61 ++++++++++++++-
 gcc/config/riscv/riscv.h                      |  3 +
 gcc/config/riscv/riscv.md                     |  4 +
 gcc/config/riscv/thead.cc                     | 77 +++++++++++++++++++
 gcc/config/riscv/thead.md                     | 67 ++++++++++++++++
 .../gcc.target/riscv/xtheadint-push-pop.c     | 36 +++++++++
 7 files changed, 247 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadint-push-pop.c

diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h
index 196b53f10f3..91d1e99f672 100644
--- a/gcc/config/riscv/riscv-protos.h
+++ b/gcc/config/riscv/riscv-protos.h
@@ -633,6 +633,9 @@ extern void th_mempair_prepare_save_restore_operands (rtx[4], bool,
 						      int, HOST_WIDE_INT,
 						      int, HOST_WIDE_INT);
 extern void th_mempair_save_restore_regs (rtx[4], bool, machine_mode);
+extern unsigned int th_int_get_mask (unsigned int);
+extern unsigned int th_int_get_save_adjustment (void);
+extern rtx th_int_adjust_cfi_prologue (unsigned int);
 #ifdef RTX_CODE
 extern const char*
 th_mempair_output_move (rtx[4], bool, machine_mode, RTX_CODE);
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index c2bd1c2ed29..6ff6f4789a4 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -94,15 +94,22 @@ along with GCC; see the file COPYING3.  If not see
 #define UNSPEC_ADDRESS_TYPE(X) \
   ((enum riscv_symbol_type) (XINT (X, 1) - UNSPEC_ADDRESS_FIRST))
 
-/* True if bit BIT is set in VALUE.  */
-#define BITSET_P(VALUE, BIT) (((VALUE) & (1ULL << (BIT))) != 0)
-
 /* Extract the backup dynamic frm rtl.  */
 #define DYNAMIC_FRM_RTL(c) ((c)->machine->mode_sw_info.dynamic_frm)
 
 /* True the mode switching has static frm, or false.  */
 #define STATIC_FRM_P(c) ((c)->machine->mode_sw_info.static_frm_p)
 
+/* True if we can use the instructions in the XTheadInt extension
+   to handle interrupts, or false.  */
+#define TH_INT_INTERRUPT(c)						\
+  (TARGET_XTHEADINT							\
+   /* The XTheadInt extension only supports rv32.  */			\
+   && !TARGET_64BIT							\
+   && (c)->machine->interrupt_handler_p					\
+   /* The XTheadInt instructions can only be executed in M-mode.  */	\
+   && (c)->machine->interrupt_mode == MACHINE_MODE)
+
 /* Information about a function's frame layout.  */
 struct GTY(())  riscv_frame_info {
   /* The size of the frame in bytes.  */
@@ -6737,6 +6744,7 @@ riscv_expand_prologue (void)
   unsigned fmask = frame->fmask;
   int spimm, multi_push_additional, stack_adj;
   rtx insn, dwarf = NULL_RTX;
+  unsigned th_int_mask = 0;
 
   if (flag_stack_usage_info)
     current_function_static_stack_size = constant_lower_bound (remaining_size);
@@ -6805,6 +6813,28 @@ riscv_expand_prologue (void)
       REG_NOTES (insn) = dwarf;
     }
 
+  th_int_mask = th_int_get_mask (frame->mask);
+  if (th_int_mask && TH_INT_INTERRUPT (cfun))
+    {
+      frame->mask &= ~th_int_mask;
+
+      /* RISCV_PROLOGUE_TEMP may be used to handle some CSR for
+	 interrupts, such as fcsr.  */
+      if ((TARGET_HARD_FLOAT  && frame->fmask)
+	  || (TARGET_ZFINX && frame->mask))
+	frame->mask |= (1 << RISCV_PROLOGUE_TEMP_REGNUM);
+
+      unsigned save_adjustment = th_int_get_save_adjustment ();
+      frame->gp_sp_offset -= save_adjustment;
+      remaining_size -= save_adjustment;
+
+      insn = emit_insn (gen_th_int_push ());
+
+      rtx dwarf = th_int_adjust_cfi_prologue (th_int_mask);
+      RTX_FRAME_RELATED_P (insn) = 1;
+      REG_NOTES (insn) = dwarf;
+    }
+
   /* Save the GP, FP registers.  */
   if ((frame->mask | frame->fmask) != 0)
     {
@@ -7033,6 +7063,7 @@ riscv_expand_epilogue (int style)
     = use_multi_pop ? frame->multi_push_adj_base + frame->multi_push_adj_addi
 		    : 0;
   rtx ra = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
+  unsigned th_int_mask = 0;
   rtx insn;
 
   /* We need to add memory barrier to prevent read from deallocated stack.  */
@@ -7195,12 +7226,32 @@ riscv_expand_epilogue (int style)
   else if (use_restore_libcall)
     frame->mask = 0; /* Temporarily fib that we need not restore GPRs.  */
 
+  th_int_mask = th_int_get_mask (frame->mask);
+  if (th_int_mask && TH_INT_INTERRUPT (cfun))
+    {
+      frame->mask &= ~th_int_mask;
+
+      /* RISCV_PROLOGUE_TEMP may be used to handle some CSR for
+	 interrupts, such as fcsr.  */
+      if ((TARGET_HARD_FLOAT  && frame->fmask)
+	  || (TARGET_ZFINX && frame->mask))
+	frame->mask |= (1 << RISCV_PROLOGUE_TEMP_REGNUM);
+    }
+
   /* Restore the registers.  */
   riscv_for_each_saved_v_reg (step2, riscv_restore_reg, false);
   riscv_for_each_saved_reg (frame->total_size - step2 - libcall_size
 			      - multipop_size,
 			    riscv_restore_reg, true, style == EXCEPTION_RETURN);
 
+  if (th_int_mask && TH_INT_INTERRUPT (cfun))
+    {
+      frame->mask = mask; /* Undo the above fib.  */
+      unsigned save_adjustment = th_int_get_save_adjustment ();
+      gcc_assert (step2.to_constant () >= save_adjustment);
+      step2 -= save_adjustment;
+    }
+
   if (use_restore_libcall)
     frame->mask = mask; /* Undo the above fib.  */
 
@@ -7263,7 +7314,9 @@ riscv_expand_epilogue (int style)
 
       gcc_assert (mode != UNKNOWN_MODE);
 
-      if (mode == MACHINE_MODE)
+      if (th_int_mask && TH_INT_INTERRUPT (cfun))
+	emit_jump_insn (gen_th_int_pop ());
+      else if (mode == MACHINE_MODE)
 	emit_jump_insn (gen_riscv_mret ());
       else if (mode == SUPERVISOR_MODE)
 	emit_jump_insn (gen_riscv_sret ());
diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h
index 6205d7533f4..4c04a5d4c22 100644
--- a/gcc/config/riscv/riscv.h
+++ b/gcc/config/riscv/riscv.h
@@ -629,6 +629,9 @@ enum reg_class
   (!SMALL_OPERAND (VALUE)						\
    && SMALL_OPERAND (VALUE & ~(HOST_WIDE_INT_1U << floor_log2 (VALUE))))
 
+/* True if bit BIT is set in VALUE.  */
+#define BITSET_P(VALUE, BIT) (((VALUE) & (1ULL << (BIT))) != 0)
+
 /* Stack layout; function entry, exit and calling.  */
 
 #define STACK_GROWS_DOWNWARD 1
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 8f28e8e56ab..4023cacf7c0 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -126,6 +126,10 @@ (define_c_enum "unspecv" [
   ;; XTheadFmv unspec
   UNSPEC_XTHEADFMV
   UNSPEC_XTHEADFMV_HW
+
+  ;; XTheadInt unspec
+  UNSPECV_XTHEADINT_PUSH
+  UNSPECV_XTHEADINT_POP
 ])
 
 (define_constants
diff --git a/gcc/config/riscv/thead.cc b/gcc/config/riscv/thead.cc
index a485fb1fba6..b444a0b478f 100644
--- a/gcc/config/riscv/thead.cc
+++ b/gcc/config/riscv/thead.cc
@@ -945,3 +945,80 @@ th_print_operand_address (FILE *file, machine_mode mode, rtx x)
 
   gcc_unreachable ();
 }
+
+/* Number array of registers X1, X5-X7, X10-X17, X28-X31, to be
+   operated on by instruction th.ipush/th.ipop in XTheadInt.  */
+
+int th_int_regs[] ={
+  RETURN_ADDR_REGNUM,
+  T0_REGNUM, T1_REGNUM, T2_REGNUM,
+  A0_REGNUM, A1_REGNUM, A2_REGNUM, A3_REGNUM,
+  A4_REGNUM, A5_REGNUM, A6_REGNUM, A7_REGNUM,
+  T3_REGNUM, T4_REGNUM, T5_REGNUM, T6_REGNUM,
+};
+
+/* If MASK contains registers X1, X5-X7, X10-X17, X28-X31, then
+   return the mask composed of these registers, otherwise return
+   zero.  */
+
+unsigned int
+th_int_get_mask (unsigned int mask)
+{
+  unsigned int xtheadint_mask = 0;
+
+  if (!TARGET_XTHEADINT || TARGET_64BIT)
+    return 0;
+
+  for (unsigned int i = 0; i < ARRAY_SIZE (th_int_regs); i++)
+    {
+      if (!BITSET_P (mask, th_int_regs[i]))
+	return 0;
+
+      xtheadint_mask |= (1 << th_int_regs[i]);
+    }
+
+  return xtheadint_mask; /* Usually 0xf003fce2.  */
+}
+
+/* Returns the occupied frame needed to save registers X1, X5-X7,
+   X10-X17, X28-X31.  */
+
+unsigned int
+th_int_get_save_adjustment (void)
+{
+  gcc_assert (TARGET_XTHEADINT && !TARGET_64BIT);
+  return ARRAY_SIZE (th_int_regs) * UNITS_PER_WORD;
+}
+
+rtx
+th_int_adjust_cfi_prologue (unsigned int mask)
+{
+  gcc_assert (TARGET_XTHEADINT && !TARGET_64BIT);
+
+  rtx dwarf = NULL_RTX;
+  rtx adjust_sp_rtx, reg, mem, insn;
+  int saved_size = ARRAY_SIZE (th_int_regs) * UNITS_PER_WORD;
+  int offset = saved_size;
+
+  for (int regno = GP_REG_FIRST; regno <= GP_REG_LAST; regno++)
+    if (BITSET_P (mask, regno - GP_REG_FIRST))
+      {
+	offset -= UNITS_PER_WORD;
+	reg = gen_rtx_REG (SImode, regno);
+	mem = gen_frame_mem (SImode, plus_constant (Pmode,
+						    stack_pointer_rtx,
+						    offset));
+
+	insn = gen_rtx_SET (mem, reg);
+	dwarf = alloc_reg_note (REG_CFA_OFFSET, insn, dwarf);
+      }
+
+  /* Debug info for adjust sp.  */
+  adjust_sp_rtx =
+    gen_rtx_SET (stack_pointer_rtx,
+		 gen_rtx_PLUS (GET_MODE (stack_pointer_rtx),
+			       stack_pointer_rtx, GEN_INT (-saved_size)));
+  dwarf = alloc_reg_note (REG_CFA_ADJUST_CFA, adjust_sp_rtx, dwarf);
+
+  return dwarf;
+}
diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
index 2babfafb23c..4d6e16c0edc 100644
--- a/gcc/config/riscv/thead.md
+++ b/gcc/config/riscv/thead.md
@@ -210,6 +210,73 @@ (define_insn "th_fmv_x_hw"
    (set_attr "type" "fmove")
    (set_attr "mode" "DF")])
 
+;; XTheadInt
+
+(define_constants
+  [(T0_REGNUM	5)
+   (T1_REGNUM	6)
+   (T2_REGNUM	7)
+   (A0_REGNUM	10)
+   (A1_REGNUM	11)
+   (A2_REGNUM	12)
+   (A3_REGNUM	13)
+   (A4_REGNUM	14)
+   (A5_REGNUM	15)
+   (A6_REGNUM	16)
+   (A7_REGNUM	17)
+   (T3_REGNUM	28)
+   (T4_REGNUM	29)
+   (T5_REGNUM	30)
+   (T6_REGNUM	31)
+])
+
+(define_insn "th_int_push"
+  [(unspec_volatile [(const_int 0)] UNSPECV_XTHEADINT_PUSH)
+   (use (reg:SI RETURN_ADDR_REGNUM))
+   (use (reg:SI T0_REGNUM))
+   (use (reg:SI T1_REGNUM))
+   (use (reg:SI T2_REGNUM))
+   (use (reg:SI A0_REGNUM))
+   (use (reg:SI A1_REGNUM))
+   (use (reg:SI A2_REGNUM))
+   (use (reg:SI A3_REGNUM))
+   (use (reg:SI A4_REGNUM))
+   (use (reg:SI A5_REGNUM))
+   (use (reg:SI A6_REGNUM))
+   (use (reg:SI A7_REGNUM))
+   (use (reg:SI T3_REGNUM))
+   (use (reg:SI T4_REGNUM))
+   (use (reg:SI T5_REGNUM))
+   (use (reg:SI T6_REGNUM))]
+  "TARGET_XTHEADINT && !TARGET_64BIT"
+  "th.ipush"
+  [(set_attr "type"	"store")
+   (set_attr "mode"	"SI")])
+
+(define_insn "th_int_pop"
+  [(unspec_volatile [(const_int 0)] UNSPECV_XTHEADINT_POP)
+   (clobber (reg:SI RETURN_ADDR_REGNUM))
+   (clobber (reg:SI T0_REGNUM))
+   (clobber (reg:SI T1_REGNUM))
+   (clobber (reg:SI T2_REGNUM))
+   (clobber (reg:SI A0_REGNUM))
+   (clobber (reg:SI A1_REGNUM))
+   (clobber (reg:SI A2_REGNUM))
+   (clobber (reg:SI A3_REGNUM))
+   (clobber (reg:SI A4_REGNUM))
+   (clobber (reg:SI A5_REGNUM))
+   (clobber (reg:SI A6_REGNUM))
+   (clobber (reg:SI A7_REGNUM))
+   (clobber (reg:SI T3_REGNUM))
+   (clobber (reg:SI T4_REGNUM))
+   (clobber (reg:SI T5_REGNUM))
+   (clobber (reg:SI T6_REGNUM))
+   (return)]
+  "TARGET_XTHEADINT && !TARGET_64BIT"
+  "th.ipop"
+  [(set_attr "type"	"ret")
+   (set_attr "mode"	"SI")])
+
 ;; XTheadMac
 
 (define_insn "*th_mula<mode>"
diff --git a/gcc/testsuite/gcc.target/riscv/xtheadint-push-pop.c b/gcc/testsuite/gcc.target/riscv/xtheadint-push-pop.c
new file mode 100644
index 00000000000..dc5609c8f76
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/xtheadint-push-pop.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc_xtheadint -mabi=ilp32d" { target { rv32 } } } */
+/* { dg-options "-march=rv64gc_xtheadint -mabi=lp64d" { target { rv64 } } } */
+
+extern void f (void);
+
+__attribute__ ((interrupt))
+void func_default (void)
+{
+  f ();
+}
+
+__attribute__ ((interrupt ("machine")))
+void func_machine (void)
+{
+  f ();
+}
+
+/* { dg-final { scan-assembler-times {\mth\.ipush\M} 2 { target { rv32 } } } } */
+/* { dg-final { scan-assembler-times {\mth\.ipop\M} 2 { target { rv32 } } } } */
+
+
+__attribute__ ((interrupt ("user")))
+void func_usr (void)
+{
+  f ();
+}
+
+__attribute__ ((interrupt ("supervisor")))
+void func_supervisor (void)
+{
+  f ();
+}
+
+/* { dg-final { scan-assembler-not {\mth\.ipush\M} { target { rv64 } } } } */
+/* { dg-final { scan-assembler-not {\mth\.ipop\M} { target { rv64 } } } } */

base-commit: 37183018134049a70482a59b8f12180946ab8fa4
-- 
2.17.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re:[PATCH v2] RISC-V: T-HEAD: Add support for the XTheadInt ISA extension
  2023-11-17  7:33     ` [PATCH v2] RISC-V: T-HEAD: " Jin Ma
@ 2024-01-09  9:35       ` Jin Ma
  2024-01-09 17:59       ` [PATCH " Jeff Law
  1 sibling, 0 replies; 20+ messages in thread
From: Jin Ma @ 2024-01-09  9:35 UTC (permalink / raw)
  To: Jin Ma, gcc-patches
  Cc: kito.cheng, christoph.muellner, jinma.contrib, jeffreyalaw, palmer

ping

Ref: https://gcc.gnu.org/pipermail/gcc-patches/2023-November/636932.html

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2] RISC-V: T-HEAD: Add support for the XTheadInt ISA extension
  2023-11-17  7:33     ` [PATCH v2] RISC-V: T-HEAD: " Jin Ma
  2024-01-09  9:35       ` Jin Ma
@ 2024-01-09 17:59       ` Jeff Law
  2024-01-10 17:56         ` Christoph Müllner
  1 sibling, 1 reply; 20+ messages in thread
From: Jeff Law @ 2024-01-09 17:59 UTC (permalink / raw)
  To: Jin Ma, gcc-patches; +Cc: kito.cheng, christoph.muellner, jinma.contrib



On 11/17/23 00:33, Jin Ma wrote:
> The XTheadInt ISA extension provides acceleration interruption
> instructions as defined in T-Head-specific:
> * th.ipush
> * th.ipop
> 
> Ref:
> https://github.com/T-head-Semi/thead-extension-spec/releases/download/2.3.0/xthead-2023-11-10-2.3.0.pdf
> 
> gcc/ChangeLog:
> 
> 	* config/riscv/riscv-protos.h (th_int_get_mask): New prototype.
> 	(th_int_get_save_adjustment): Likewise.
> 	(th_int_adjust_cfi_prologue): Likewise.
> 	* config/riscv/riscv.cc (TH_INT_INTERRUPT): New macro.
> 	(riscv_expand_prologue): Add the processing of XTheadInt.
> 	(riscv_expand_epilogue): Likewise.
> 	* config/riscv/riscv.md: New unspec.
> 	* config/riscv/thead.cc (BITSET_P): New macro.
> 	* config/riscv/thead.md (th_int_push): New pattern.
> 	(th_int_pop): New pattern.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* gcc.target/riscv/xtheadint-push-pop.c: New test.
Thanks for the ping earlier today.  I've looked at this patch repeatedly 
over the last few weeks, but never enough to give it a full review.


> diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
> index 2babfafb23c..4d6e16c0edc 100644
> --- a/gcc/config/riscv/thead.md
> +++ b/gcc/config/riscv/thead.md

> +(define_insn "th_int_pop"
> +  [(unspec_volatile [(const_int 0)] UNSPECV_XTHEADINT_POP)
> +   (clobber (reg:SI RETURN_ADDR_REGNUM))
> +   (clobber (reg:SI T0_REGNUM))
> +   (clobber (reg:SI T1_REGNUM))
> +   (clobber (reg:SI T2_REGNUM))
> +   (clobber (reg:SI A0_REGNUM))
> +   (clobber (reg:SI A1_REGNUM))
> +   (clobber (reg:SI A2_REGNUM))
> +   (clobber (reg:SI A3_REGNUM))
> +   (clobber (reg:SI A4_REGNUM))
> +   (clobber (reg:SI A5_REGNUM))
> +   (clobber (reg:SI A6_REGNUM))
> +   (clobber (reg:SI A7_REGNUM))
> +   (clobber (reg:SI T3_REGNUM))
> +   (clobber (reg:SI T4_REGNUM))
> +   (clobber (reg:SI T5_REGNUM))
> +   (clobber (reg:SI T6_REGNUM))
> +   (return)]
> +  "TARGET_XTHEADINT && !TARGET_64BIT"
> +  "th.ipop"
> +  [(set_attr "type"	"ret")
> +   (set_attr "mode"	"SI")])
I probably would have gone with a load type since its the loads that are 
most likely to interact existing code in the pipeline.  But I doubt it 
really matters in practice.


OK for the trunk.  Thanks for your patience.

jeff

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2] RISC-V: T-HEAD: Add support for the XTheadInt ISA extension
  2024-01-09 17:59       ` [PATCH " Jeff Law
@ 2024-01-10 17:56         ` Christoph Müllner
  0 siblings, 0 replies; 20+ messages in thread
From: Christoph Müllner @ 2024-01-10 17:56 UTC (permalink / raw)
  To: Jeff Law; +Cc: Jin Ma, gcc-patches, kito.cheng, jinma.contrib, Philipp Tomsich

On Tue, Jan 9, 2024 at 6:59 PM Jeff Law <jeffreyalaw@gmail.com> wrote:
>
>
>
> On 11/17/23 00:33, Jin Ma wrote:
> > The XTheadInt ISA extension provides acceleration interruption
> > instructions as defined in T-Head-specific:
> > * th.ipush
> > * th.ipop
> >
> > Ref:
> > https://github.com/T-head-Semi/thead-extension-spec/releases/download/2.3.0/xthead-2023-11-10-2.3.0.pdf
> >
> > gcc/ChangeLog:
> >
> >       * config/riscv/riscv-protos.h (th_int_get_mask): New prototype.
> >       (th_int_get_save_adjustment): Likewise.
> >       (th_int_adjust_cfi_prologue): Likewise.
> >       * config/riscv/riscv.cc (TH_INT_INTERRUPT): New macro.
> >       (riscv_expand_prologue): Add the processing of XTheadInt.
> >       (riscv_expand_epilogue): Likewise.
> >       * config/riscv/riscv.md: New unspec.
> >       * config/riscv/thead.cc (BITSET_P): New macro.
> >       * config/riscv/thead.md (th_int_push): New pattern.
> >       (th_int_pop): New pattern.
> >
> > gcc/testsuite/ChangeLog:
> >
> >       * gcc.target/riscv/xtheadint-push-pop.c: New test.
> Thanks for the ping earlier today.  I've looked at this patch repeatedly
> over the last few weeks, but never enough to give it a full review.
>
>
> > diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md
> > index 2babfafb23c..4d6e16c0edc 100644
> > --- a/gcc/config/riscv/thead.md
> > +++ b/gcc/config/riscv/thead.md
>
> > +(define_insn "th_int_pop"
> > +  [(unspec_volatile [(const_int 0)] UNSPECV_XTHEADINT_POP)
> > +   (clobber (reg:SI RETURN_ADDR_REGNUM))
> > +   (clobber (reg:SI T0_REGNUM))
> > +   (clobber (reg:SI T1_REGNUM))
> > +   (clobber (reg:SI T2_REGNUM))
> > +   (clobber (reg:SI A0_REGNUM))
> > +   (clobber (reg:SI A1_REGNUM))
> > +   (clobber (reg:SI A2_REGNUM))
> > +   (clobber (reg:SI A3_REGNUM))
> > +   (clobber (reg:SI A4_REGNUM))
> > +   (clobber (reg:SI A5_REGNUM))
> > +   (clobber (reg:SI A6_REGNUM))
> > +   (clobber (reg:SI A7_REGNUM))
> > +   (clobber (reg:SI T3_REGNUM))
> > +   (clobber (reg:SI T4_REGNUM))
> > +   (clobber (reg:SI T5_REGNUM))
> > +   (clobber (reg:SI T6_REGNUM))
> > +   (return)]
> > +  "TARGET_XTHEADINT && !TARGET_64BIT"
> > +  "th.ipop"
> > +  [(set_attr "type"  "ret")
> > +   (set_attr "mode"  "SI")])
> I probably would have gone with a load type since its the loads that are
> most likely to interact existing code in the pipeline.  But I doubt it
> really matters in practice.
>
>
> OK for the trunk.  Thanks for your patience.

I've retested this locally (no regressions), completed the ChangeLog
in the commit message and committed.

Thanks,
Christoph

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2024-01-10 17:56 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-13 21:46 [PATCH 0/7] Add XThead* support Christoph Muellner
2022-11-13 21:46 ` [PATCH 1/7] riscv: Add basic XThead* vendor extension support Christoph Muellner
2022-11-13 21:46 ` [PATCH 2/7] riscv: riscv-cores.def: Add T-Head XuanTie C906 Christoph Muellner
2022-11-18  4:50   ` cooper.qu
2022-11-18  4:58     ` Palmer Dabbelt
2022-11-13 21:46 ` [PATCH 3/7] riscv: thead: Add support for XTheadBa and XTheadBs ISA extensions Christoph Muellner
2022-11-13 21:46 ` [PATCH 4/7] riscv: thead: Add support for XTheadCondMov " Christoph Muellner
2022-11-13 21:46 ` [PATCH 5/7] riscv: thead: Add support for XTheadBb ISA extension Christoph Muellner
2022-11-18  4:21   ` cooper.qu
2022-11-13 21:46 ` [PATCH 6/7] riscv: thead: Add support for XTheadMac " Christoph Muellner
2022-11-13 21:46 ` [PATCH 7/7] riscv: Add basic extension support for XTheadFmv and XTheadInt Christoph Muellner
2022-11-18  4:43   ` cooper.qu
2023-11-02  7:26   ` [RE] [7/7] " Jin Ma
2023-11-02  7:42     ` Christoph Müllner
2023-11-07  3:04   ` [PATCH] riscv: thead: Add support for the XTheadInt ISA extension Jin Ma
2023-11-10 15:05     ` Christoph Müllner
2023-11-17  7:33     ` [PATCH v2] RISC-V: T-HEAD: " Jin Ma
2024-01-09  9:35       ` Jin Ma
2024-01-09 17:59       ` [PATCH " Jeff Law
2024-01-10 17:56         ` Christoph Müllner

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).