Per the discussion a couple weeks ago in the patchwork call, I'm
submitting the spacemit-x60 basic core and tuning info on Austin's behalf.
I know everyone would like to have performance data, but with 8%+ run to
run variation with the same binary and ~10hr cycle times for spec2017
(integer ref only), getting data with any degree of confidence is
exceedingly hard when the improvements are expected to be in the low
single digits. It just takes so many runs to get a reasonable
confidence interval.
This also does not include the vector pipeline model. I think we know
how we want to model it, but it's not really started yet. Per our
discussion this (and further twiddles to the tuning/pipeline model) can
be made during stage3/stage4 given the low risk of breaking anything.
We're also likely going to want to make adjustments to the vector cost
structure. Right now it's using the generic cost structure. Overall it
looks like the spacemit-x60 has better than expected segment support,
but worse than expected stride support. So the trick of using strides
to avoid the permute in SATD likely isn't viable (setting aside the
unaligned vector element issues).
Anyway, the goal is to get the basics in place so that the -mcpu/-mtune
options work and we can iterate on finer details.
I'll wait for pre-commit CI to do its thing. There's no rush to commit,
just to get it submitted :-) I have no plans to work in Pago Pago
tonight to get anything else submitted before the stage1 close deadline.
Jeff
* config/riscv/riscv-cores.def: Add RISCV_TUNE and RISCV_CORE entries
for the spacemit-x60 design.
* config/riscv/riscv-opts.h (riscv_microarchitecture_type): Add entry
for spacemit-x60 design.
* config/riscv/riscv.cc (spacemit_x60_tune_info): New tune structure
for the spacemit-x60 design.
* config/riscv/riscv.md (tune): Add spacemit_x60.
Include spacemit-x60.md.
* config/riscv/spacemit-x60.md: New file
* doc/riscv-mtune.texi: Regenerate.
* doc/riscv-mcpu.texi: Regenerate.
diff --git a/gcc/config/riscv/riscv-cores.def b/gcc/config/riscv/riscv-cores.def
index 19d27b8998f7..abe9d496cda6 100644
--- a/gcc/config/riscv/riscv-cores.def
+++ b/gcc/config/riscv/riscv-cores.def
@@ -50,6 +50,7 @@ RISCV_TUNE("xt-c920", generic, generic_ooo_tune_info)
RISCV_TUNE("xt-c920v2", generic, generic_ooo_tune_info)
RISCV_TUNE("xiangshan-nanhu", xiangshan, xiangshan_nanhu_tune_info)
RISCV_TUNE("xiangshan-kunminghu", xiangshan, generic_ooo_tune_info)
+RISCV_TUNE("spacemit-x60", spacemit_x60, spacemit_x60_tune_info)
RISCV_TUNE("generic-ooo", generic_ooo, generic_ooo_tune_info)
RISCV_TUNE("size", generic, optimize_size_tune_info)
RISCV_TUNE("mips-p8700", mips_p8700, mips_p8700_tune_info)
@@ -180,5 +181,8 @@ RISCV_CORE("andes-nx25",
"rv64imc_zicsr_zifencei_xandesperf", "andes-25-
RISCV_CORE("andes-ax25", "rv64imafdc_zicsr_zifencei_xandesperf",
"andes-25-series")
RISCV_CORE("andes-a27", "rv32imafdc_zicsr_zifencei_xandesperf",
"andes-25-series")
RISCV_CORE("andes-ax27", "rv64imafdc_zicsr_zifencei_xandesperf",
"andes-25-series")
+RISCV_CORE("spacemit-x60", "rv64imafdcv_zba_zbb_zbc_zbs_zicboz_zicond_"
+ "zbkc_zfh_zvfh_zvkt_zvl256b_sscofpmf",
+ "spacemit-x60")
#undef RISCV_CORE
diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
index 95c032d33d23..bca5382485c3 100644
--- a/gcc/config/riscv/riscv-opts.h
+++ b/gcc/config/riscv/riscv-opts.h
@@ -62,6 +62,7 @@ enum riscv_microarchitecture_type {
mips_p8700,
tt_ascalon_d8,
andes_25_series,
+ spacemit_x60,
};
extern enum riscv_microarchitecture_type riscv_microarchitecture;
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 3c994a0cd55e..844a008880bb 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -756,6 +756,30 @@ static const struct riscv_tune_param andes_25_tune_info = {
NULL, /* vector cost */
NULL, /* function_align */
NULL, /* jump_align */
+ NULL, /* loop_align. */
+ true, /* prefer-agnostic. */
+};
+
+static const struct riscv_tune_param spacemit_x60_tune_info= {
+ {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_add */
+ {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_mul */
+ {COSTS_N_INSNS (15), COSTS_N_INSNS (22)}, /* fp_div */
+ {COSTS_N_INSNS (3), COSTS_N_INSNS (6)}, /* int_mul */
+ {COSTS_N_INSNS (12), COSTS_N_INSNS (20)}, /* int_div */
+ 2, /* issue_rate */
+ 3, /* branch_cost */
+ 5, /* memory_cost */
+ 6, /* fmv_cost */
+ false, /* slow_unaligned_access */
+ false, /* vector_unaligned_access */
+ false, /* use_divmod_expansion */
+ false, /* overlap_op_by_pieces */
+ false, /* use_zero_stride_load */
+ true, /*
speculative_sched_vsetvl */
+ RISCV_FUSE_NOTHING, /* fusible_ops */
+ NULL, /* vector cost */
+ NULL, /* function_align */
+ NULL, /* jump_align */
NULL, /* loop_align */
true, /* prefer-agnostic. */
};
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index fced2da2e604..59233babfc32 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -673,7 +673,7 @@ (define_attr "cannot_copy" "no,yes" (const_string "no"))
;; Keep this in sync with enum riscv_microarchitecture.
(define_attr "tune"
"generic,sifive_7,sifive_p400,sifive_p600,xiangshan,generic_ooo,mips_p8700,
- tt_ascalon_d8,andes_25_series"
+ tt_ascalon_d8,andes_25_series,spacemit_x60"
(const (symbol_ref "((enum attr_tune) riscv_microarchitecture)")))
;; Describe a user's asm statement.
@@ -4989,3 +4989,4 @@ (define_split
(include "generic-ooo.md")
(include "tt-ascalon-d8.md")
(include "andes-25-series.md")
+(include "spacemit-x60.md")
diff --git a/gcc/config/riscv/spacemit-x60.md b/gcc/config/riscv/spacemit-x60.md
new file mode 100644
index 000000000000..c991f89e5e2d
--- /dev/null
+++ b/gcc/config/riscv/spacemit-x60.md
@@ -0,0 +1,190 @@
+;; spacemit_x60 DFA-based pipeline description for RISC-V targets.
+;; Copyright (C) 2011-2025 Free Software Foundation, Inc.
+;; Contributed by Andrew Waterman ([email protected]).
+;; Based on MIPS target for GNU compiler.
+
+;; 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/>.
+
+;; ----------------------------------------------------
+;; Spacemit-x60 Units
+;; 2*alu + 2*lsu + 1*fpalu + 1*fdivsqrt + 1*vxu
+;;
+;; There's actually two VXU units and ops get split across them
+;; to give the illusion of a single wider unit with higher
+;; performance. There are a few ops that can only be fed into
+;; one of the two units. Probably best to initially model as
+;; a single unit
+;;
+;; The VXU is not currently modeled.
+;; Some ops like shadd.uw and add.uw, cpop take an extra cycle
+;; Given everything is in-order, anti-dependencies probably matter
+;; FP sign injection isn't handled correctly
+;; ----------------------------------------------------
+
+(define_automaton "spacemit_x60")
+(define_cpu_unit "spacemit_x60_alu0,spacemit_x60_alu1" "spacemit_x60")
+(define_cpu_unit "spacemit_x60_lsu0,spacemit_x60_lsu1" "spacemit_x60")
+;;(define_cpu_unit "spacemit_x60_vxu0" "spacemit_x60")
+(define_cpu_unit "spacemit_x60_fpalu" "spacemit_x60")
+(define_cpu_unit "spacemit_x60_fdivsqrt" "spacemit_x60")
+
+(define_reservation "spacemit_x60_lsu" "spacemit_x60_lsu0, spacemit_x60_lsu1")
+(define_reservation "spacemit_x60_alu" "spacemit_x60_alu0, spacemit_x60_alu1")
+
+;; ----------------------------------------------------
+;; Memory (load/store)
+;; ----------------------------------------------------
+
+(define_insn_reservation "spacemit_x60_load" 5
+ (and (eq_attr "tune" "spacemit_x60")
+ (eq_attr "type" "load,fpload,atomic"))
+ "spacemit_x60_lsu")
+
+(define_insn_reservation "spacemit_x60_store" 3
+ (and (eq_attr "tune" "spacemit_x60")
+ (eq_attr "type" "store,fpstore"))
+ "spacemit_x60_lsu")
+
+;; ----------------------------------------------------
+;; Int
+;; ----------------------------------------------------
+
+;; alu0 handles div/rem and jumps
+(define_insn_reservation "spacemit_x60_jump" 1
+ (and (eq_attr "tune" "spacemit_x60")
+ (eq_attr "type" "branch,jump,call,jalr,ret,trap,sfb_alu"))
+ "spacemit_x60_alu0")
+
+(define_insn_reservation "spacemit_x60_idivsi" 12
+ (and (eq_attr "tune" "spacemit_x60")
+ (and (eq_attr "type" "idiv")
+ (eq_attr "mode" "SI")))
+ "spacemit_x60_alu0*12")
+
+(define_insn_reservation "spacemit_x60_idivdi" 20
+ (and (eq_attr "tune" "spacemit_x60")
+ (and (eq_attr "type" "idiv")
+ (eq_attr "mode" "DI")))
+ "spacemit_x60_alu0*20")
+
+(define_insn_reservation "spacemit_x60_imulsi" 3
+ (and (eq_attr "tune" "spacemit_x60")
+ (and (eq_attr "type" "imul")
+ (eq_attr "mode" "SI")))
+ "spacemit_x60_alu")
+
+(define_insn_reservation "spacemit_x60_imuldi" 5
+ (and (eq_attr "tune" "spacemit_x60")
+ (and (eq_attr "type" "imul")
+ (eq_attr "mode" "DI")))
+ "spacemit_x60_alu")
+
+(define_insn_reservation "spacemit_x60_clmul" 5
+ (and (eq_attr "tune" "spacemit_x60")
+ (eq_attr "type" "clmul"))
+ "spacemit_x60_alu")
+
+(define_insn_reservation "spacemit_x60_mtc_mfc" 3
+ (and (eq_attr "tune" "spacemit_x60")
+ (eq_attr "type" "mtc,mfc"))
+ "spacemit_x60_alu")
+
+(define_insn_reservation "spacemit_x60_fcvt_i2f" 4
+ (and (eq_attr "tune" "spacemit_x60")
+ (eq_attr "type" "fcvt_i2f"))
+ "spacemit_x60_alu")
+
+(define_insn_reservation "spacemit_x60_fcvt_f2i" 6
+ (and (eq_attr "tune" "spacemit_x60")
+ (eq_attr "type" "fcvt_f2i"))
+ "spacemit_x60_alu")
+
+(define_insn_reservation "spacemit_x60_alu" 1
+ (and (eq_attr "tune" "spacemit_x60")
+ (eq_attr "type" "unknown,const,arith,shift,slt,multi,auipc,nop,logical,\
+ move,bitmanip,min,max,minu,maxu,clz,ctz,rotate,\
+ condmove,crypto,mvpair,zicond,cpop"))
+ "spacemit_x60_alu")
+
+(define_insn_reservation "spacemit_x60_alu2c" 2
+ (and (eq_attr "tune" "spacemit_x60")
+ (eq_attr "type" "cpop"))
+ "spacemit_x60_alu")
+
+;; ----------------------------------------------------
+;; Float
+;; ----------------------------------------------------
+
+(define_insn_reservation "spacemit_x60_fcvt" 4
+ (and (eq_attr "tune" "spacemit_x60")
+ (eq_attr "type" "fcvt,fmove"))
+ "spacemit_x60_fpalu")
+
+(define_insn_reservation "spacemit_x60_fcmp" 6
+ (and (eq_attr "tune" "spacemit_x60")
+ (eq_attr "type" "fcmp"))
+ "spacemit_x60_fpalu")
+
+(define_insn_reservation "spacemit_x60_fmul_half_single" 4
+ (and (eq_attr "tune" "spacemit_x60")
+ (and (eq_attr "type" "fadd,fmul")
+ (ior (eq_attr "mode" "HF")
+ (eq_attr "mode" "SF"))))
+ "spacemit_x60_fpalu")
+
+(define_insn_reservation "spacemit_x60_fmadd_half_single" 5
+ (and (eq_attr "tune" "spacemit_x60")
+ (and (eq_attr "type" "fmadd")
+ (ior (eq_attr "mode" "HF")
+ (eq_attr "mode" "SF"))))
+ "spacemit_x60_fpalu")
+
+(define_insn_reservation "spacemit_x60_fmul_double" 5
+ (and (eq_attr "tune" "spacemit_x60")
+ (and (eq_attr "type" "fadd,fmul")
+ (eq_attr "mode" "DF")))
+ "spacemit_x60_fpalu")
+
+(define_insn_reservation "spacemit_x60_fmadd_double" 5
+ (and (eq_attr "tune" "spacemit_x60")
+ (and (eq_attr "type" "fmadd")
+ (eq_attr "mode" "DF")))
+ "spacemit_x60_fpalu")
+
+(define_insn_reservation "spacemit_x60_fdiv_half" 12
+ (and (eq_attr "tune" "spacemit_x60")
+ (and (eq_attr "type" "fdiv,fsqrt")
+ (eq_attr "mode" "HF")))
+ "spacemit_x60_fdivsqrt*12")
+
+(define_insn_reservation "spacemit_x60_fdiv_single" 15
+ (and (eq_attr "tune" "spacemit_x60")
+ (and (eq_attr "type" "fdiv,fsqrt")
+ (eq_attr "mode" "SF")))
+ "spacemit_x60_fdivsqrt*15")
+
+(define_insn_reservation "spacemit_x60_fdiv_double" 22
+ (and (eq_attr "tune" "spacemit_x60")
+ (and (eq_attr "type" "fdiv,fsqrt")
+ (eq_attr "mode" "DF")))
+ "spacemit_x60_fdivsqrt*22")
+
+(define_insn_reservation "spacemi6_x60_dummy" 1
+ (and (eq_attr "tune" "spacemit_x60")
+ (eq_attr "type"
"viminmax,vfmuladd,vfmovvf,vssegte,vlsegds,rdvlenb,vaesef,vfcmp,vmpop,vwsll,vsha2cl,vfwcvtbf16,vfncvtftoi,vgather,vsha2ch,vsts,vldm,vmsfs,vfmul,vcompress,vaesz,vssegtox,vstox,vclmulh,vghsh,vaalu,vslideup,vfalu,vaeskf1,vfcvtitof,vaesdm,vmffs,vandn,vstm,vgmul,vlds,viwmul,vfmerge,vlsegdff,vshift,vaesem,vaesdf,vste,ghost,viwred,vsalu,vfwredu,vmidx,sf_vfnrclip,vstux,vfslide1down,vfcvtftoi,vfncvtitof,vnshift,vsm3me,vired,vlde,vfwalu,sf_vc_se,vlsegdux,vicmp,vfncvtftof,vror,vfwmaccbf16,vfminmax,vldff,vstr,vsm3c,vfwcvtftoi,vbrev,vaeskf2,vidiv,vfwcvtftof,rdvl,vimul,vfsgnj,vimovvx,vsha2ms,vialu,vfredo,vctz,vlsegde,viwmuladd,vcpop,vsetvl,vldux,vfwmuladd,vector,wrvxrm,vsshift,vfredu,vimerge,vlsegdox,vfrecp,vnclip,vfclass,vbrev8,vslidedown,vldox,vmalu,vext,vimuladd,sf_vqmacc,vldr,vrol,vmov,vsmul,vclmul,vfmov,vislide1up,vssegtux,vclz,rdfrm,vfwcvtitof,vfncvtbf16,vfmovfv,vislide1down,vfwmul,vfsqrt,vrev8,vicalu,vimov,wrfrm,vfdiv,sf_vc,vsm4k,vmiota,vsm4r,viwalu,vsetvl_pre,vimovxv,vfwredo,vfslide1up,vssegts"))
+ "nothing")
+
diff --git a/gcc/doc/riscv-mcpu.texi b/gcc/doc/riscv-mcpu.texi
index f79edfb837c8..8fcba597ad19 100644
--- a/gcc/doc/riscv-mcpu.texi
+++ b/gcc/doc/riscv-mcpu.texi
@@ -80,4 +80,6 @@ by particular CPU name. Permissible values for this option
are:
@samp{andes-a27},
-@samp{andes-ax27}.
+@samp{andes-ax27},
+
+@samp{spacemit-x60}.
diff --git a/gcc/doc/riscv-mtune.texi b/gcc/doc/riscv-mtune.texi
index cf713670fd69..02fcd342384a 100644
--- a/gcc/doc/riscv-mtune.texi
+++ b/gcc/doc/riscv-mtune.texi
@@ -50,6 +50,8 @@ particular CPU name. Permissible values for this option are:
@samp{xiangshan-kunminghu},
+@samp{spacemit-x60},
+
@samp{generic-ooo},
@samp{size},