diff --git a/gcc/config/riscv/arcv-rmx100.md b/gcc/config/riscv/arcv-rmx100.md new file mode 100644 index 000000000000..5a25dfb67cfc --- /dev/null +++ b/gcc/config/riscv/arcv-rmx100.md @@ -0,0 +1,103 @@ +;; DFA scheduling description of the Synopsys RMX-100 cpu +;; for GNU C compiler +;; Copyright (C) 2023 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 +;; . + +(define_automaton "arcv_rmx100") + +(define_cpu_unit "arcv_rmx100_ALU" "arcv_rmx100") +;(define_cpu_unit "arcv_rmx100_CSR" "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*35") + +; 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,nothing*2") + +(define_insn_reservation "arcv_rmx100_store_insn" 1 + (and (eq_attr "tune" "arcv_rmx100") + (eq_attr "type" "store,fpstore")) + "arcv_rmx100_DMP") + +;; FPU scheduling. FIXME: This is based on the "fast" unit for now, the "slow" +;; option remains to be implemented later (together with the -mfpu flag). + +(define_insn_reservation "arcv_rmx100_fpload_insn" 3 + (and (eq_attr "tune" "arcv_rmx100") + (eq_attr "type" "fpload")) + "arcv_rmx100_DMP,nothing*2") + +(define_insn_reservation "arcv_rmx100_farith_insn" 2 + (and (eq_attr "tune" "arcv_rmx100") + (eq_attr "type" "fadd,fcmp")) + "arcv_rmx100_FPU,nothing") + +(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,nothing") + +(define_insn_reservation "arcv_rmx100_fmac_insn" 2 + (and (eq_attr "tune" "arcv_rmx100") + (eq_attr "type" "fmadd")) + "arcv_rmx100_FPU,nothing") + +(define_insn_reservation "arcv_rmx100_fdiv_insn" 10 + (and (eq_attr "tune" "arcv_rmx100") + (eq_attr "type" "fdiv,fsqrt")) + "arcv_rmx100_FPU") + + +(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") diff --git a/gcc/config/riscv/riscv-cores.def b/gcc/config/riscv/riscv-cores.def index cc9d5c03cb8c..d1708f3785b6 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("arc-v-rmx-100-series", arcv_rmx100, arcv_rmx100_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) diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h index 4e4e9d8930e2..7be10413b4d9 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, + arcv_rmx100, }; extern enum riscv_microarchitecture_type riscv_microarchitecture; @@ -85,6 +86,13 @@ enum rvv_max_lmul_enum { RVV_DYNAMIC = 9 }; +/* 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, diff --git a/gcc/config/riscv/riscv-protos.h b/gcc/config/riscv/riscv-protos.h index 570acb14f585..5881cb9529ce 100644 --- a/gcc/config/riscv/riscv-protos.h +++ b/gcc/config/riscv/riscv-protos.h @@ -165,6 +165,9 @@ extern bool riscv_epilogue_uses (unsigned int); extern bool riscv_can_use_return_insn (void); extern rtx riscv_function_value (const_tree, const_tree, enum machine_mode); extern bool riscv_store_data_bypass_p (rtx_insn *, rtx_insn *); +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 rtx riscv_gen_gpr_save_insn (struct riscv_frame_info *); extern bool riscv_gpr_save_operation_p (rtx); extern void riscv_reinit (void); diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index e186c6a99e9d..8719c2942b55 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -685,6 +685,30 @@ static const struct riscv_tune_param tt_ascalon_d8_tune_info = { true, /* prefer-agnostic. */ }; +/* 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 */ + 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 */ +}; + /* Costs to use when optimizing for size. */ static const struct riscv_tune_param optimize_size_tune_info = { {COSTS_N_INSNS (1), COSTS_N_INSNS (1)}, /* fp_add */ @@ -10466,6 +10490,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 rhx100.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 diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 640ca5f9b0ea..823f8dda8a30 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -672,7 +672,7 @@ ;; 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,arcv_rmx100" (const (symbol_ref "((enum attr_tune) riscv_microarchitecture)"))) ;; Describe a user's asm statement. @@ -4966,3 +4966,4 @@ (include "generic-vector-ooo.md") (include "generic-ooo.md") (include "tt-ascalon-d8.md") +(include "arcv-rmx100.md") diff --git a/gcc/config/riscv/riscv.opt b/gcc/config/riscv/riscv.opt index 6543fd1c4a72..663acf62dac4 100644 --- a/gcc/config/riscv/riscv.opt +++ b/gcc/config/riscv/riscv.opt @@ -396,3 +396,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 -param=arcv_mpy_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) + +-param=arcv-mpy-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=rmx100) (default: 2c). diff --git a/gcc/doc/riscv-mtune.texi b/gcc/doc/riscv-mtune.texi index a2a4d3e77dbb..63a01db67726 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{arc-v-rmx-100-series}, + @samp{generic-ooo}, @samp{size},