]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[PATCH v2] RISC-V: Add Synopsys RMX-100 series pipeline description.
authorMichiel Derhaeg <Michiel.Derhaeg@synopsys.com>
Fri, 1 May 2026 13:41:54 +0000 (07:41 -0600)
committerJeff Law <jeffrey.law@oss.qualcomm.com>
Fri, 1 May 2026 13:43:09 +0000 (07:43 -0600)
This patch introduces the pipeline description for the Synopsys RMX-100 series
processor to the RISC-V GCC backend.  The RMX-100 has a short, three-stage,
in-order execution pipeline with configurable multiply unit options.

The option -mmpy-option was added to control which version of the MPY unit the
core has and what the latency of multiply instructions should be similar to
ARCv2 cores (see gcc/config/arc/arc.opt:60).

gcc/ChangeLog:

* config/riscv/riscv-cores.def (RISCV_TUNE): Add arc-v-rmx-100-series.
* config/riscv/riscv-opts.h (enum riscv_microarchitecture_type):
Add arcv_rmx100.
(enum arcv_mpy_option_enum): New enum for ARC-V multiply options.
* config/riscv/riscv-protos.h (arcv_mpy_1c_bypass_p): New declaration.
(arcv_mpy_2c_bypass_p): New declaration.
(arcv_mpy_10c_bypass_p): New declaration.
* config/riscv/riscv.cc (arcv_mpy_1c_bypass_p): New function.
(arcv_mpy_2c_bypass_p): New function.
(arcv_mpy_10c_bypass_p): New function.
* config/riscv/riscv.md: Add arcv_rmx100.
* config/riscv/riscv.opt: New option for RMX-100 multiply unit
configuration.
* doc/riscv-mtune.texi: Document arc-v-rmx-100-series.
* config/riscv/arcv-rmx100.md: New file.

Co-authored-by: Artemiy Volkov <artemiyv@acm.org>
Co-authored-by: Luis Silva <luiss@synopsys.com>
Signed-off-by: Michiel Derhaeg <michiel@synopsys.com>
gcc/config/riscv/arcv-rmx100.md [new file with mode: 0644]
gcc/config/riscv/riscv-cores.def
gcc/config/riscv/riscv-opts.h
gcc/config/riscv/riscv-protos.h
gcc/config/riscv/riscv.cc
gcc/config/riscv/riscv.md
gcc/config/riscv/riscv.opt
gcc/doc/riscv-mtune.texi

diff --git a/gcc/config/riscv/arcv-rmx100.md b/gcc/config/riscv/arcv-rmx100.md
new file mode 100644 (file)
index 0000000..e573a45
--- /dev/null
@@ -0,0 +1,127 @@
+;; DFA scheduling description of the Synopsys RMX-100 cpu
+;; for GNU C compiler
+;; Copyright (C) 2026 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_automaton "arcv_rmx100")
+
+(define_cpu_unit "arcv_rmx100_ALU"    "arcv_rmx100")
+(define_cpu_unit "arcv_rmx100_FPU"    "arcv_rmx100")
+(define_cpu_unit "arcv_rmx100_MPY"    "arcv_rmx100")
+(define_cpu_unit "arcv_rmx100_DIV"    "arcv_rmx100")
+(define_cpu_unit "arcv_rmx100_DMP"    "arcv_rmx100")
+
+;; Instruction reservation for arithmetic instructions.
+(define_insn_reservation "arcv_rmx100_alu_arith" 1
+  (and (eq_attr "tune" "arcv_rmx100")
+       (eq_attr "type" "unknown, const, arith, shift, slt, multi, auipc, nop,
+                       logical, move, atomic, mvpair, bitmanip, clz, ctz, cpop,
+                       zicond, condmove, clmul, min, max, minu, maxu, rotate"))
+  "arcv_rmx100_ALU")
+
+(define_insn_reservation "arcv_rmx100_jmp_insn" 1
+  (and (eq_attr "tune" "arcv_rmx100")
+       (eq_attr "type" "branch, jump, call, jalr, ret, trap"))
+  "arcv_rmx100_ALU")
+
+; DIV insn: latency may be overridden by a define_bypass
+(define_insn_reservation "arcv_rmx100_div_insn" 35
+  (and (eq_attr "tune" "arcv_rmx100")
+       (eq_attr "type" "idiv"))
+  "arcv_rmx100_DIV*7")
+
+; MPY insn: latency may be overridden by a define_bypass
+(define_insn_reservation "arcv_rmx100_mpy32_insn" 9
+  (and (eq_attr "tune" "arcv_rmx100")
+       (eq_attr "type" "imul"))
+  "arcv_rmx100_MPY")
+
+(define_insn_reservation "arcv_rmx100_load_insn" 3
+  (and (eq_attr "tune" "arcv_rmx100")
+       (eq_attr "type" "load"))
+  "arcv_rmx100_DMP")
+
+(define_insn_reservation "arcv_rmx100_store_insn" 1
+  (and (eq_attr "tune" "arcv_rmx100")
+       (eq_attr "type" "store,fpstore"))
+  "arcv_rmx100_DMP")
+
+;; FPU scheduling.  This is based on the "fast" unit for now.
+
+(define_insn_reservation "arcv_rmx100_fpload_insn" 3
+  (and (eq_attr "tune" "arcv_rmx100")
+       (eq_attr "type" "fpload"))
+  "arcv_rmx100_DMP")
+
+(define_insn_reservation "arcv_rmx100_farith_insn" 2
+  (and (eq_attr "tune" "arcv_rmx100")
+       (eq_attr "type" "fadd,fcmp"))
+  "arcv_rmx100_FPU")
+
+(define_insn_reservation "arcv_rmx100_xfer" 1
+  (and (eq_attr "tune" "arcv_rmx100")
+       (eq_attr "type" "fmove,mtc,mfc,fcvt,fcvt_f2i,fcvt_i2f"))
+   "arcv_rmx100_FPU")
+
+(define_insn_reservation "arcv_rmx100_fmul_insn" 2
+  (and (eq_attr "tune" "arcv_rmx100")
+       (eq_attr "type" "fmul"))
+  "arcv_rmx100_FPU")
+
+(define_insn_reservation "arcv_rmx100_fmac_insn" 2
+  (and (eq_attr "tune" "arcv_rmx100")
+       (eq_attr "type" "fmadd"))
+  "arcv_rmx100_FPU")
+
+(define_insn_reservation "arcv_rmx100_fdiv_insn" 10
+  (and (eq_attr "tune" "arcv_rmx100")
+       (eq_attr "type" "fdiv,fsqrt"))
+  "arcv_rmx100_FPU")
+
+(define_insn_reservation "arcv_rmx100_unknown" 5
+  (and (eq_attr "tune" "arcv_rmx100")
+       (eq_attr "type" "vfwalu,vfwcvtftoi,vrol,vmidx,vext,vaeskf1,vfredo,
+                        vector,sfb_alu,vlds,viminmax,vfcmp,vimov,vsmul,vnclip,
+                        vldm,vsetvl_pre,vwsll,vfmerge,vmffs,vclmul,vmpop,wrfrm,
+                        vsha2ms,vidiv,vfncvtitof,vaesef,vldr,vlsegdox,vfwmul,
+                        vfmul,vfredu,crypto,vmalu,vimul,vghsh,vialu,viwmul,
+                        vfcvtftoi,vaalu,vislide1up,vfcvtitof,vfwcvtftof,vgather,
+                        vaesz,vbrev,vshift,vsha2ch,vssegtux,vssegtox,vcompress,
+                        vcpop,vstux,vfncvtftof,vfrecp,vssegts,sf_vfnrclip,
+                        vstox,vstr,vlsegdff,vired,vimovvx,vislide1down,vclz,
+                        vfwredu,rdvl,vlde,vaesem,vsm3me,vmiota,vldux,vlsegde,
+                        vssegte,vfwmaccbf16,vfwredo,vctz,vsm4k,vsshift,vsts,
+                        vmsfs,vfmovvf,vfslide1down,viwred,vslidedown,vfncvtftoi,
+                        vsm3c,vnshift,vfalu,vfsqrt,wrvxrm,vfmuladd,vmov,vsetvl,
+                        vfclass,vsha2cl,vicmp,vldff,vfdiv,vste,vaeskf2,
+                        vfncvtbf16,vandn,vbrev8,vgmul,vaesdm,vlsegdux,vfsgnj,
+                        vfmov,rdfrm,vlsegds,vclmulh,vimuladd,viwalu,vfwmuladd,
+                        vimerge,vror,rdvlenb,vfwcvtitof,vaesdf,viwmuladd,vrev8,
+                        vsm4r,vsalu,vfminmax,vicalu,vslideup,vldox,vstm,
+                        vfwcvtbf16,vfmovfv,vfslide1up,vimovxv,sf_vc,sf_vqmacc,
+                        sf_vc_se"))
+  "arcv_rmx100_ALU")
+
+
+(define_bypass 1 "arcv_rmx100_mpy32_insn"
+  "arcv_rmx100_*" "arcv_mpy_1c_bypass_p")
+(define_bypass 2 "arcv_rmx100_mpy32_insn"
+  "arcv_rmx100_*" "arcv_mpy_2c_bypass_p")
+
+(define_bypass 9 "arcv_rmx100_div_insn" "arcv_rmx100_*" "arcv_mpy_1c_bypass_p")
+(define_bypass 9 "arcv_rmx100_div_insn" "arcv_rmx100_*" "arcv_mpy_2c_bypass_p")
index 66f1dc7031519a70f8a466c4663c535a1b0922af..257eae1168a266b36a76294800f3a89010abd87c 100644 (file)
@@ -58,6 +58,7 @@ RISCV_TUNE("mips-p8700", mips_p8700, mips_p8700_tune_info)
 RISCV_TUNE("andes-25-series", andes_25_series, andes_25_tune_info)
 RISCV_TUNE("andes-23-series", andes_23_series, andes_23_tune_info)
 RISCV_TUNE("andes-45-series", andes_45_series, andes_45_tune_info)
+RISCV_TUNE("arc-v-rmx-100-series", arcv_rmx100, arcv_rmx100_tune_info)
 
 #undef RISCV_TUNE
 
index d4bd4310076439086bd14b9e3048e3fc7ac100c0..88a4aa33926317a34baa38cadce6504a940c25ab 100644 (file)
@@ -65,6 +65,7 @@ enum riscv_microarchitecture_type {
   andes_23_series,
   andes_45_series,
   spacemit_x60,
+  arcv_rmx100,
   arcv_rhx100
 };
 extern enum riscv_microarchitecture_type riscv_microarchitecture;
@@ -93,6 +94,13 @@ enum rvv_max_lmul_enum {
   RVV_CONV_DYNAMIC = 10
 };
 
+/* ARC-V multiply option.  */
+enum arcv_mpy_option_enum {
+  ARCV_MPY_OPTION_1C = 1,
+  ARCV_MPY_OPTION_2C = 2,
+  ARCV_MPY_OPTION_10C = 8,
+};
+
 enum riscv_multilib_select_kind {
   /* Select multilib by builtin way.  */
   select_by_builtin,
index 494feb4458de1c816b3fcbcb8fd5d3b2b201517a..5bdccfb317c4d07188bf2a190bfbee3b8f249fa5 100644 (file)
@@ -840,6 +840,10 @@ extern const char *th_output_move (rtx, rtx);
 extern bool th_print_operand_address (FILE *, machine_mode, rtx);
 #endif
 
+extern bool arcv_mpy_1c_bypass_p (rtx_insn *, rtx_insn *);
+extern bool arcv_mpy_2c_bypass_p (rtx_insn *, rtx_insn *);
+extern bool arcv_mpy_10c_bypass_p (rtx_insn *, rtx_insn *);
+
 extern bool strided_load_broadcast_p (void);
 extern bool riscv_prefer_agnostic_p (void);
 extern bool riscv_use_divmod_expander (void);
index 7cb9798349295539ab9bfa4e9c41a6286c28802b..53888f17710c2c9da8ffb363fe46d2b94c7ec485 100644 (file)
@@ -863,6 +863,31 @@ static const struct riscv_tune_param arcv_rhx100_tune_info = {
 };
 
 
+/* Costs to use when optimizing for Synopsys RMX-100.  */
+static const struct riscv_tune_param arcv_rmx100_tune_info = {
+  {COSTS_N_INSNS (2), COSTS_N_INSNS (2)},      /* fp_add */
+  {COSTS_N_INSNS (2), COSTS_N_INSNS (2)},      /* fp_mul */
+  {COSTS_N_INSNS (17), COSTS_N_INSNS (17)},    /* fp_div */
+  {COSTS_N_INSNS (2), COSTS_N_INSNS (2)},      /* int_mul */
+  {COSTS_N_INSNS (17), COSTS_N_INSNS (17)},    /* int_div */
+  1,                                           /* issue_rate */
+  4,                                           /* branch_cost */
+  2,                                           /* memory_cost */
+  4,                                           /* fmv_cost */
+  false,                                       /* slow_unaligned_access */
+  false,                                       /* vector_unaligned_access */
+  true,                                                /* use_divmod_expansion */
+  false,                                       /* overlap_op_by_pieces */
+  true,                                                /* use_zero_stride_load */
+  false,                                       /* speculative_sched_vsetvl */
+  RISCV_FUSE_NOTHING,                          /* fusible_ops */
+  NULL,                                                /* vector cost */
+  NULL,                                                /* function_align */
+  NULL,                                                /* jump_align */
+  NULL,                                                /* loop_align */
+  true,                                                /* prefer-agnostic.  */
+};
+
 static bool riscv_avoid_shrink_wrapping_separate ();
 static tree riscv_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
 static tree riscv_handle_type_attribute (tree *, tree, tree, int, bool *);
@@ -10770,6 +10795,30 @@ riscv_store_data_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn)
   return store_data_bypass_p (out_insn, in_insn);
 }
 
+/* Implement one boolean function for each of the values of the
+   arcv_mpy_option enum, for the needs of arcv-rmx100.md.  */
+
+bool
+arcv_mpy_1c_bypass_p (rtx_insn *out_insn ATTRIBUTE_UNUSED,
+                      rtx_insn *in_insn ATTRIBUTE_UNUSED)
+{
+  return arcv_mpy_option == ARCV_MPY_OPTION_1C;
+}
+
+bool
+arcv_mpy_2c_bypass_p (rtx_insn *out_insn ATTRIBUTE_UNUSED,
+                      rtx_insn *in_insn ATTRIBUTE_UNUSED)
+{
+  return arcv_mpy_option == ARCV_MPY_OPTION_2C;
+}
+
+bool
+arcv_mpy_10c_bypass_p (rtx_insn *out_insn ATTRIBUTE_UNUSED,
+                       rtx_insn *in_insn ATTRIBUTE_UNUSED)
+{
+  return arcv_mpy_option == ARCV_MPY_OPTION_10C;
+}
+
 /* Implement TARGET_SECONDARY_MEMORY_NEEDED.
 
    When floating-point registers are wider than integer ones, moves between
index 43be603396346ccc2b3bca0e201eacbbd521db01..4a49e778fed54f242d585513153fa857b919c7b9 100644 (file)
 (define_attr "tune"
   "generic,sifive_7,sifive_p400,sifive_p600,xiangshan,generic_ooo,mips_p8700,
    tt_ascalon_d8,andes_25_series,andes_23_series,andes_45_series,spacemit_x60,
-   arcv_rhx100"
+   arcv_rmx100,arcv_rhx100"
   (const (symbol_ref "((enum attr_tune) riscv_microarchitecture)")))
 
 ;; Describe a user's asm statement.
 (include "andes-25-series.md")
 (include "andes-45-series.md")
 (include "spacemit-x60.md")
+(include "arcv-rmx100.md")
 (include "arcv-rhx100.md")
index 2c26ee99691315d1374d6e5d4ddebf30f259eb1f..c6e099eb47e0c7cde4d27e0a8e7d532fe08dddfe 100644 (file)
@@ -423,3 +423,20 @@ Specifies whether the fence.tso instruction should be used.
 mautovec-segment
 Target Integer Var(riscv_mautovec_segment) Init(1)
 Enable (default) or disable generation of vector segment load/store instructions.
+
+Enum
+Name(arcv_mpy_option) Type(enum arcv_mpy_option_enum)
+Valid arguments to -mmpy_option=:
+
+EnumValue
+Enum(arcv_mpy_option) String(1c) Value(ARCV_MPY_OPTION_1C)
+
+EnumValue
+Enum(arcv_mpy_option) String(2c) Value(ARCV_MPY_OPTION_2C)
+
+EnumValue
+Enum(arcv_mpy_option) String(10c) Value(ARCV_MPY_OPTION_10C)
+
+mmpy-option=
+Target RejectNegative Joined Enum(arcv_mpy_option) Var(arcv_mpy_option) Init(ARCV_MPY_OPTION_2C)
+The type of MPY unit used by the RMX-100 core (to be used in combination with -mtune=arc-v-rmx-100-series) (default: 2c).
index 6ceb9a93facf4ccc032d59ea734f95633e635324..7ab6f63454099dda8811df4bd3d21ebe10f52a47 100644 (file)
@@ -66,4 +66,6 @@ particular CPU name.  Permissible values for this option are:
 
 @samp{andes-45-series},
 
+@samp{arc-v-rmx-100-series},
+
 and all valid options for @option{-mcpu=}.