gcc/ChangeLog:

        * config/riscv/riscv-cores.def (RISCV_TUNE): Add andes-25-series.
        (RISCV_CORE): Add Andes 25-series cpu list.
        * config/riscv/riscv-opts.h
        (enum riscv_microarchitecture_type): Add andes_vicuna.
        * config/riscv/riscv.cc: Add andes_vicuna_tune_info.
        * config/riscv/riscv.md: Add andes_vicuna.
        * doc/riscv-mcpu.texi: Regenerated for Andes cpu list.
        * doc/riscv-mtune.texi: Regenerated for andes-25-series.
        * config/riscv/andes-vicuna.md: New file.
---
 gcc/config/riscv/andes-vicuna.md | 322 +++++++++++++++++++++++++++++++
 gcc/config/riscv/riscv-cores.def |  10 +
 gcc/config/riscv/riscv-opts.h    |   1 +
 gcc/config/riscv/riscv.cc        |  24 +++
 gcc/config/riscv/riscv.md        |   4 +-
 gcc/doc/riscv-mcpu.texi          |  16 +-
 gcc/doc/riscv-mtune.texi         |   2 +
 7 files changed, 377 insertions(+), 2 deletions(-)
 create mode 100644 gcc/config/riscv/andes-vicuna.md

diff --git a/gcc/config/riscv/andes-vicuna.md b/gcc/config/riscv/andes-vicuna.md
new file mode 100644
index 00000000000..a1e0d4642c1
--- /dev/null
+++ b/gcc/config/riscv/andes-vicuna.md
@@ -0,0 +1,322 @@
+;; DFA-based pipeline description for Andes Vicuna.
+;;
+;; Copyright (C) 2025 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 "vicuna_pipe0, vicuna_vector")
+
+;; Integer pipeline
+(define_cpu_unit "vicuna_pipe" "vicuna_pipe0")
+;; Division operation unit
+(define_cpu_unit "vicuna_mdu" "vicuna_pipe0")
+;; Floating point units
+(define_cpu_unit "vicuna_fpu, vicuna_fpu_eu" "vicuna_pipe0")
+
+;; Vector execution unit.
+(define_cpu_unit "vicuna_vpu_lsu, vicuna_vpu_alu, vicuna_vpu_mac,
+                 vicuna_vpu_msk, vicuna_vpu_div, vicuna_vpu_fmac,
+                 vicuna_vpu_fmis, vicuna_vpu_perm, vicuna_vpu_pipe"
+                "vicuna_vector")
+
+;; andes vicuna unsupported insns are mapped to dummies reservations
+(define_reservation "andes_vicuna_dummies"
+  "vicuna_pipe | vicuna_mdu | vicuna_fpu"
+)
+
+;; andes vicuna vector unsupported insns are mapped to dummies reservations
+(define_reservation "andes_vicuna_vector_dummies"
+  "vicuna_vpu_lsu | vicuna_vpu_alu | vicuna_vpu_mac | vicuna_vpu_msk |
+   vicuna_vpu_div | vicuna_vpu_fmac | vicuna_vpu_fmis | vicuna_vpu_perm |
+   vicuna_vpu_pipe"
+)
+
+(define_reservation "vicuna_fpu_arith"
+  "(vicuna_pipe + vicuna_fpu), vicuna_fpu_eu * 2")
+
+(define_reservation "vicuna_fpu_pipe"
+  "vicuna_pipe + vicuna_fpu")
+
+(define_insn_reservation "vicuna_alu_insn" 1
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "unknown,const,arith,shift,slt,multi,nop,logical,move,
+                       auipc,atomic"))
+  "vicuna_pipe")
+
+(define_insn_reservation "vicuna_load_wd" 2
+  (and (eq_attr "tune" "andes_vicuna")
+       (and (eq_attr "type" "load")
+           (not (eq_attr "mode" "QI,HI"))))
+  "vicuna_pipe")
+
+(define_insn_reservation "vicuna_load_bh" 3
+  (and (eq_attr "tune" "andes_vicuna")
+       (and (eq_attr "type" "load")
+           (eq_attr "mode" "QI,HI")))
+  "vicuna_pipe")
+
+(define_insn_reservation "vicuna_store" 0
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "store"))
+  "vicuna_pipe")
+
+(define_insn_reservation "vicuna_branch" 0
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "branch,jump,call,jalr,trap,ret"))
+  "vicuna_pipe")
+
+(define_insn_reservation "vicuna_imul" 3
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "imul"))
+  "vicuna_pipe")
+
+(define_insn_reservation "vicuna_idivsi" 38
+  (and (eq_attr "tune" "andes_vicuna")
+       (and (eq_attr "type" "idiv")
+           (eq_attr "mode" "SI")))
+  "vicuna_pipe, vicuna_mdu * 34")
+
+(define_insn_reservation "vicuna_idivdi" 70
+  (and (eq_attr "tune" "andes_vicuna")
+       (and (eq_attr "type" "idiv")
+           (eq_attr "mode" "DI")))
+  "vicuna_pipe, vicuna_mdu * 66")
+
+(define_insn_reservation "vicuna_xfer" 1
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "mfc,mtc"))
+  "vicuna_pipe")
+
+(define_insn_reservation "vicuna_fpu_alu" 5
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "fadd"))
+  "vicuna_fpu_arith")
+
+(define_insn_reservation "vicuna_fpu_mul" 5
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "fmul"))
+  "vicuna_fpu_arith")
+
+(define_insn_reservation "vicuna_fpu_mac" 5
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "fmadd"))
+  "vicuna_fpu_arith")
+
+(define_insn_reservation "vicuna_fpu_div" 33
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "fdiv"))
+  "vicuna_fpu_arith, vicuna_fpu_eu * 27")
+
+(define_insn_reservation "vicuna_fpu_sqrt" 33
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "fsqrt"))
+  "vicuna_fpu_arith, vicuna_fpu_eu * 27")
+
+(define_insn_reservation "vicuna_fpu_move" 3
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "fmove,mtc,mfc"))
+  "vicuna_fpu_pipe")
+
+(define_insn_reservation "vicuna_fpu_cmp" 3
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "fcmp"))
+  "vicuna_fpu_pipe")
+
+(define_insn_reservation "vicuna_fpu_cvt" 6
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "fcvt,fcvt_i2f,fcvt_f2i"))
+  "vicuna_fpu_arith, vicuna_fpu_eu")
+
+(define_insn_reservation "vicuna_fpu_load" 3
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "fpload"))
+  "vicuna_fpu_pipe")
+
+(define_insn_reservation "vicuna_fpu_store" 0
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "fpstore"))
+  "vicuna_fpu_pipe")
+
+(define_insn_reservation "vicuna_bitmanip" 1
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "bitmanip"))
+  "vicuna_pipe")
+
+;; Vector pipeline.
+
+(define_insn_reservation "vicuna_vload" 5
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "vlde,vldm,vlds,vldff,vldr"))
+  "(vicuna_vpu_pipe + vicuna_vpu_lsu)*3")
+
+(define_insn_reservation "vicuna_index_vload" 8
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "vldux,vldox"))
+  "(vicuna_vpu_pipe + vicuna_vpu_lsu)*3")
+
+(define_insn_reservation "vicuna_seg_vload" 16
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "vlsegde,vlsegds,vlsegdux,vlsegdox,vlsegdff"))
+  "(vicuna_vpu_pipe + vicuna_vpu_lsu)*3")
+
+(define_insn_reservation "vicuna_vstore" 0
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "vste,vstm,vsts,vstux,vstox,vstr,vssegte,\
+                       vssegts,vssegtux,vssegtox"))
+  "(vicuna_vpu_pipe + vicuna_vpu_lsu)*3")
+
+(define_insn_reservation "vicuna_vialu" 1
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "vialu,vicalu,vshift,viminmax,vicmp,vimov,\
+                       vsalu,vaalu,vmov,vector,vimerge"))
+  "vicuna_vpu_pipe + vicuna_vpu_alu")
+  
+(define_insn_reservation "vicuna_widen_vialu" 2
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "viwalu, vext, vsshift"))
+  "vicuna_vpu_pipe + vicuna_vpu_alu")
+  
+(define_insn_reservation "vicuna_narrow_vialu" 3
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "vnshift,vnclip"))
+  "vicuna_vpu_pipe + vicuna_vpu_alu")
+  
+(define_insn_reservation "vicuna_vimul" 2
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "vimul,vimuladd,vsmul"))
+  "vicuna_vpu_pipe + vicuna_vpu_mac")
+
+(define_insn_reservation "vicuna_widen_vimul" 3
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "viwmul,viwmuladd"))
+  "vicuna_vpu_pipe + vicuna_vpu_mac")
+
+(define_insn_reservation "vicuna_vperm" 3
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "vslideup,vslidedown,vislide1up,vislide1down,\
+                       vfslide1up,vfslide1down,vgather"))
+  "vicuna_vpu_pipe + vicuna_vpu_perm")
+  
+(define_insn_reservation "vicuna_vcompress" 4
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "vcompress"))
+  "vicuna_vpu_pipe + vicuna_vpu_perm")
+
+(define_insn_reservation "vicuna_vmovv" 7
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "vimovvx,vfmovvf"))
+  "(vicuna_vpu_pipe + vicuna_vpu_perm)*5")
+
+(define_insn_reservation "vicuna_vmovx" 3
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "vimovxv,vfmovfv,vfmov"))
+  "vicuna_vpu_pipe + vicuna_vpu_perm")
+
+(define_insn_reservation "vicuna_vreduction" 3
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "vired,viwred"))
+  "vicuna_vpu_pipe + vicuna_vpu_alu*5")
+
+(define_insn_reservation "vicuna_vidiv" 35
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "vidiv"))
+  "vicuna_vpu_pipe + vicuna_vpu_div*34")
+
+(define_insn_reservation "vicuna_vmask_2" 2
+  (eq_attr "type" "vmalu,vmsfs")
+  "vicuna_vpu_pipe + vicuna_vpu_msk")
+
+(define_insn_reservation "vicuna_vmask_3" 3
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "vmiota,vmidx"))
+  "vicuna_vpu_pipe + vicuna_vpu_msk")
+
+(define_insn_reservation "vicuna_vpopc" 6
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "vmpop"))
+  "vicuna_vpu_pipe + vicuna_vpu_msk")
+
+(define_insn_reservation "vicuna_vffs" 7
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "vmffs"))
+  "vicuna_vpu_pipe + vicuna_vpu_msk")
+
+(define_insn_reservation "vicuna_vfadd" 4
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "vfalu,vfwalu,vfmul,vfwmul,vfmuladd,\
+                       vfwmuladd"))
+  "vicuna_vpu_pipe + vicuna_vpu_fmac")
+
+(define_insn_reservation "vicuna_vfdiv" 39
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "vfdiv,vfsqrt"))
+  "vicuna_vpu_pipe + vicuna_vpu_div*19")
+
+(define_insn_reservation "vicuna_vfmis" 2
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "vfminmax,vfcmp,vfsgnj,vfclass,vfmerge"))
+  "vicuna_vpu_pipe + vicuna_vpu_fmis")
+
+(define_insn_reservation "vicuna_vfrecp" 3
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "vfrecp"))
+  "vicuna_vpu_pipe + vicuna_vpu_div")
+
+(define_insn_reservation "vicuna_vfcvt" 2
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "vfcvtitof,vfcvtftoi"))
+  "vicuna_vpu_pipe + vicuna_vpu_fmis")
+
+(define_insn_reservation "vicuna_widen_vfcvt" 5
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "vfwcvtitof,vfwcvtftoi,vfwcvtftof,vfwcvtbf16"))
+  "vicuna_vpu_pipe + vicuna_vpu_fmis")
+
+(define_insn_reservation "vicuna_narrow_vfcvt" 4
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "vfncvtitof,vfncvtftoi,vfncvtftof,vfncvtbf16"))
+  "vicuna_vpu_pipe + vicuna_vpu_fmis")
+
+(define_insn_reservation "vicuna_vfreduction" 6
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "vfredu,vfwredu,vfredo,vfwredo"))
+  "vicuna_vpu_pipe + vicuna_vpu_fmac*24")
+
+(define_insn_reservation "vicuna_vesetvl" 1
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "vsetvl,vsetvl_pre"))
+  "vicuna_vpu_pipe")
+
+(define_insn_reservation "vicuna_vcsr" 1
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "wrvxrm,wrfrm,rdvlenb,rdvl"))
+  "vicuna_vpu_pipe")
+
+(define_insn_reservation "andes_vicuna_unknown" 1
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "ghost,cpop,clz,ctz,zicond,mvpair,sfb_alu,minu,maxu,
+                       min,max,clmul,rotate,crypto,condmove,rdfrm"))
+  "andes_vicuna_dummies")
+
+(define_insn_reservation "andes_vicuna_vector_unknown" 1
+  (and (eq_attr "tune" "andes_vicuna")
+       (eq_attr "type" "vclz,vror,vsha2ch,vsm4k,vaesef,vghsh,vsm4r,vsm3c,
+                       vaeskf1,vandn,vaesdm,vclmul,vclmulh,vrol,vcpop,vbrev8,
+                       vsm3me,vbrev,vctz,vgmul,vsha2ms,vaesz,vrev8,
+                       vaeskf2,vsha2cl,vwsll,vaesdf,vaesem,vfwmaccbf16,
+                       sf_vqmacc,sf_vc,sf_vc_se,sf_vfnrclip"))
+  "andes_vicuna_vector_dummies")
diff --git a/gcc/config/riscv/riscv-cores.def b/gcc/config/riscv/riscv-cores.def
index cc9d5c03cb8..3393a7f7051 100644
--- a/gcc/config/riscv/riscv-cores.def
+++ b/gcc/config/riscv/riscv-cores.def
@@ -53,6 +53,7 @@ RISCV_TUNE("xiangshan-kunminghu", xiangshan, 
generic_ooo_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)
+RISCV_TUNE("andes-25-series", andes_vicuna, andes_vicuna_tune_info)
 
 #undef RISCV_TUNE
 
@@ -171,4 +172,13 @@ RISCV_CORE("xiangshan-kunminghu",   
"rv64imafdcbvh_sdtrig_sha_shcounterenw_"
 
 RISCV_CORE("mips-p8700",      "rv64imfd_zicsr_zifencei_zalrsc_zba_zbb",
                              "mips-p8700")
+
+RISCV_CORE("andes-n22",       "rv32imc_zicsr_zifencei_xandesperf",    
"andes-25-series")
+RISCV_CORE("andes-n25",       "rv32imc_zicsr_zifencei_xandesperf",    
"andes-25-series")
+RISCV_CORE("andes-a25",       "rv32imafdc_zicsr_zifencei_xandesperf", 
"andes-25-series")
+RISCV_CORE("andes-nx25",      "rv64imc_zicsr_zifencei_xandesperf",    
"andes-25-series")
+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")
+
 #undef RISCV_CORE
diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h
index 4e4e9d8930e..28c7341b41c 100644
--- a/gcc/config/riscv/riscv-opts.h
+++ b/gcc/config/riscv/riscv-opts.h
@@ -61,6 +61,7 @@ enum riscv_microarchitecture_type {
   generic_ooo,
   mips_p8700,
   tt_ascalon_d8,
+  andes_vicuna,
 };
 extern enum riscv_microarchitecture_type riscv_microarchitecture;
 
diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc
index 63404d3d514..79a52230e58 100644
--- a/gcc/config/riscv/riscv.cc
+++ b/gcc/config/riscv/riscv.cc
@@ -735,6 +735,30 @@ static const struct riscv_tune_param mips_p8700_tune_info 
= {
   true,                /* prefer-agnostic.  */
 };
 
+/* Costs to use when optimizing for Andes Vicuna.  */
+static const struct riscv_tune_param andes_vicuna_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 (20), COSTS_N_INSNS (20)},     /* fp_div */
+  {COSTS_N_INSNS (2), COSTS_N_INSNS (2)},       /* int_mul */
+  {COSTS_N_INSNS (24), COSTS_N_INSNS (24)},     /* int_div */
+  1,                                           /* issue_rate */
+  3,                                           /* branch_cost */
+  3,                                           /* memory_cost */
+  8,                                           /* fmv_cost */
+  false,                                       /* slow_unaligned_access */
+  false,                                       /* vector_unaligned_access */
+  false,                                       /* 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 */
+};
+
 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 *);
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md
index 640ca5f9b0e..74c461976e5 100644
--- a/gcc/config/riscv/riscv.md
+++ b/gcc/config/riscv/riscv.md
@@ -672,7 +672,8 @@
 ;; Microarchitectures we know how to tune for.
 ;; 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"
+  "generic,sifive_7,sifive_p400,sifive_p600,xiangshan,generic_ooo,mips_p8700,
+   tt_ascalon_d8,andes_vicuna"
   (const (symbol_ref "((enum attr_tune) riscv_microarchitecture)")))
 
 ;; Describe a user's asm statement.
@@ -4966,3 +4967,4 @@
 (include "generic-vector-ooo.md")
 (include "generic-ooo.md")
 (include "tt-ascalon-d8.md")
+(include "andes-vicuna.md")
diff --git a/gcc/doc/riscv-mcpu.texi b/gcc/doc/riscv-mcpu.texi
index 6753e510eb6..f79edfb837c 100644
--- a/gcc/doc/riscv-mcpu.texi
+++ b/gcc/doc/riscv-mcpu.texi
@@ -66,4 +66,18 @@ by particular CPU name. Permissible values for this option 
are:
 
 @samp{xiangshan-kunminghu},
 
-@samp{mips-p8700}.
+@samp{mips-p8700},
+
+@samp{andes-n22},
+
+@samp{andes-n25},
+
+@samp{andes-a25},
+
+@samp{andes-nx25},
+
+@samp{andes-ax25},
+
+@samp{andes-a27},
+
+@samp{andes-ax27}.
diff --git a/gcc/doc/riscv-mtune.texi b/gcc/doc/riscv-mtune.texi
index a2a4d3e77db..cf713670fd6 100644
--- a/gcc/doc/riscv-mtune.texi
+++ b/gcc/doc/riscv-mtune.texi
@@ -56,4 +56,6 @@ particular CPU name.  Permissible values for this option are:
 
 @samp{mips-p8700},
 
+@samp{andes-25-series},
+
 and all valid options for @option{-mcpu=}.
-- 
2.34.1

Reply via email to