[v2,1/3] RISC-V: Minimal support for ZC* extensions.

Message ID 20230607125641.727633-2-jiawei@iscas.ac.cn
State Committed
Headers
Series RISC-V: Support ZC* extensions. |

Commit Message

Jiawei June 7, 2023, 12:56 p.m. UTC
  This patch is the minimal support for ZC* extensions, include the extension
name, mask and target defination. Also define the dependencies with Zca
and Zce extension. Notes that all ZC* extensions depend on the Zca extension.
Zce includes all relevant ZC* extensions for microcontrollers using. Zce
will imply zcf when 'f' extension enabled in rv32.

Co-Authored by: Charlie Keaney <charlie.keaney@embecosm.com>
Co-Authored by: Mary Bennett <mary.bennett@embecosm.com>
Co-Authored by: Nandni Jamnadas <nandni.jamnadas@embecosm.com>
Co-Authored by: Simon Cook <simon.cook@embecosm.com>
Co-Authored by: Sinan Lin <sinan.lin@linux.alibaba.com>
Co-Authored by: Shihua Liao <shihua@iscas.ac.cn>
Co-Authored by: Yulong Shi <yulong@iscas.ac.cn>

gcc/ChangeLog:

        * common/config/riscv/riscv-common.cc (riscv_subset_list::parse): New extensions.
        * config/riscv/riscv-opts.h (MASK_ZCA): New mask.
        (MASK_ZCB): Ditto.
        (MASK_ZCE): Ditto.
        (MASK_ZCF): Ditto.
        (MASK_ZCD): Ditto.
        (MASK_ZCMP): Ditto.
        (MASK_ZCMT): Ditto.
        (TARGET_ZCA): New target.
        (TARGET_ZCB): Ditto.
        (TARGET_ZCE): Ditto.
        (TARGET_ZCF): Ditto.
        (TARGET_ZCD): Ditto.
        (TARGET_ZCMP): Ditto.
        (TARGET_ZCMT): Ditto.
        * config/riscv/riscv.opt: New target variable.

---
 gcc/common/config/riscv/riscv-common.cc | 38 +++++++++++++++++++++++++
 gcc/config/riscv/riscv-opts.h           | 16 +++++++++++
 gcc/config/riscv/riscv.opt              |  3 ++
 3 files changed, 57 insertions(+)
  

Patch

diff --git a/gcc/common/config/riscv/riscv-common.cc b/gcc/common/config/riscv/riscv-common.cc
index 3247d526c0a..89bdbef43a5 100644
--- a/gcc/common/config/riscv/riscv-common.cc
+++ b/gcc/common/config/riscv/riscv-common.cc
@@ -111,6 +111,16 @@  static const riscv_implied_info_t riscv_implied_info[] =
   {"zhinx", "zhinxmin"},
   {"zhinxmin", "zfinx"},
 
+  {"zce",  "zca"},
+  {"zce",  "zcb"},
+  {"zce",  "zcmp"},
+  {"zce",  "zcmt"},
+  {"zcf",  "zca"},
+  {"zcd",  "zca"},
+  {"zcb",  "zca"},
+  {"zcmp", "zca"},
+  {"zcmt", "zca"},
+
   {NULL, NULL}
 };
 
@@ -224,6 +234,14 @@  static const struct riscv_ext_version riscv_ext_version_table[] =
 
   {"zmmul", ISA_SPEC_CLASS_NONE, 1, 0},
 
+  {"zca",  ISA_SPEC_CLASS_NONE, 1, 0},
+  {"zcb",  ISA_SPEC_CLASS_NONE, 1, 0},
+  {"zce",  ISA_SPEC_CLASS_NONE, 1, 0},
+  {"zcf",  ISA_SPEC_CLASS_NONE, 1, 0},
+  {"zcd",  ISA_SPEC_CLASS_NONE, 1, 0},
+  {"zcmp", ISA_SPEC_CLASS_NONE, 1, 0},
+  {"zcmt", ISA_SPEC_CLASS_NONE, 1, 0},
+
   {"svinval", ISA_SPEC_CLASS_NONE, 1, 0},
   {"svnapot", ISA_SPEC_CLASS_NONE, 1, 0},
 
@@ -1156,8 +1174,19 @@  riscv_subset_list::parse (const char *arch, location_t loc)
       subset_list->handle_implied_ext (itr);
     }
 
+  /* Zce only implies zcf when RV32 and 'f' extension exist.  */
+  if (subset_list->lookup ("zce") != NULL
+	&& subset_list->m_xlen == 32
+	&& subset_list->lookup ("f") != NULL
+	&& subset_list->lookup ("zcf") == NULL)
+    subset_list->add ("zcf", false);
+
   subset_list->handle_combine_ext ();
 
+  if (subset_list->lookup ("zcf") && subset_list->m_xlen == 64)
+    error_at (loc, "%<-march=%s%>: zcf extension supports in rv32 only"
+		  , arch);
+
   if (subset_list->lookup ("zfinx") && subset_list->lookup ("f"))
     error_at (loc, "%<-march=%s%>: z*inx conflicts with floating-point "
 		   "extensions", arch);
@@ -1271,6 +1300,15 @@  static const riscv_ext_flag_table_t riscv_ext_flag_table[] =
 
   {"zmmul", &gcc_options::x_riscv_zm_subext, MASK_ZMMUL},
 
+  /* Code-size reduction extensions.  */
+  {"zca",     &gcc_options::x_riscv_zc_subext, MASK_ZCA},
+  {"zcb",     &gcc_options::x_riscv_zc_subext, MASK_ZCB},
+  {"zce",     &gcc_options::x_riscv_zc_subext, MASK_ZCE},
+  {"zcf",     &gcc_options::x_riscv_zc_subext, MASK_ZCF},
+  {"zcd",     &gcc_options::x_riscv_zc_subext, MASK_ZCD},
+  {"zcmp",    &gcc_options::x_riscv_zc_subext, MASK_ZCMP},
+  {"zcmt",    &gcc_options::x_riscv_zc_subext, MASK_ZCMT},
+
   {"svinval", &gcc_options::x_riscv_sv_subext, MASK_SVINVAL},
   {"svnapot", &gcc_options::x_riscv_sv_subext, MASK_SVNAPOT},
 
diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
index 208a557b8ff..3429fc1218e 100644
--- a/gcc/config/riscv/riscv-opts.h
+++ b/gcc/config/riscv/riscv-opts.h
@@ -215,6 +215,22 @@  enum riscv_entity
 #define MASK_ZMMUL      (1 << 0)
 #define TARGET_ZMMUL    ((riscv_zm_subext & MASK_ZMMUL) != 0)
 
+#define MASK_ZCA      (1 << 0)
+#define MASK_ZCB      (1 << 1)
+#define MASK_ZCE      (1 << 2)
+#define MASK_ZCF      (1 << 3)
+#define MASK_ZCD      (1 << 4)
+#define MASK_ZCMP     (1 << 5)
+#define MASK_ZCMT     (1 << 6)
+
+#define TARGET_ZCA    ((riscv_zc_subext & MASK_ZCA) != 0)
+#define TARGET_ZCB    ((riscv_zc_subext & MASK_ZCB) != 0)
+#define TARGET_ZCE    ((riscv_zc_subext & MASK_ZCE) != 0)
+#define TARGET_ZCF    ((riscv_zc_subext & MASK_ZCF) != 0)
+#define TARGET_ZCD    ((riscv_zc_subext & MASK_ZCD) != 0)
+#define TARGET_ZCMP   ((riscv_zc_subext & MASK_ZCMP) != 0)
+#define TARGET_ZCMT   ((riscv_zc_subext & MASK_ZCMT) != 0)
+
 #define MASK_SVINVAL (1 << 0)
 #define MASK_SVNAPOT (1 << 1)
 
diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt
index 63d4710cb15..a6fdaef61cb 100644
--- a/gcc/config/riscv/riscv.opt
+++ b/gcc/config/riscv/riscv.opt
@@ -232,6 +232,9 @@  int riscv_zf_subext
 TargetVariable
 int riscv_zm_subext
 
+TargetVariable
+int riscv_zc_subext
+
 TargetVariable
 int riscv_sv_subext