|
| 1 | +diff --git a/gcc/config/riscv/cva6.md b/gcc/config/riscv/cva6.md |
| 2 | +new file mode 100644 |
| 3 | +index 000000000..2dc397ee1 |
| 4 | +--- /dev/null |
| 5 | ++++ b/gcc/config/riscv/cva6.md |
| 6 | +@@ -0,0 +1,98 @@ |
| 7 | ++(define_automaton "cva6") |
| 8 | ++ |
| 9 | ++;; CVA6 core |
| 10 | ++;; This has 4 functional unit groups: |
| 11 | ++;; - ALU + Branch unit + Mult/Div + CSR |
| 12 | ++;; - Load unit |
| 13 | ++;; - Store Unit |
| 14 | ++;; - FPU + ALU2 (for the superscalar configuration) |
| 15 | ++ |
| 16 | ++;; Issue ports |
| 17 | ++(define_cpu_unit "cva6_issue0" "cva6") |
| 18 | ++(define_cpu_unit "cva6_issue1" "cva6") ;; if superscalar |
| 19 | ++ |
| 20 | ++;; Fixed-latency (or so-called) functional units |
| 21 | ++(define_cpu_unit "cva6_alu0" "cva6") ;; Includes the result bus |
| 22 | ++(define_cpu_unit "cva6_branch" "cva6") |
| 23 | ++(define_cpu_unit "cva6_mul" "cva6") |
| 24 | ++(define_cpu_unit "cva6_div" "cva6") |
| 25 | ++;; FIXME add CSR unit? (define_cpu_unit "cva6_csr" "cva6") |
| 26 | ++ |
| 27 | ++;; Accelerator/CV-X-IF functional unit |
| 28 | ++(define_cpu_unit "cva6_cvxif" "cva6") |
| 29 | ++ |
| 30 | ++;; Load-Store Unit |
| 31 | ++(define_cpu_unit "cva6_load" "cva6") |
| 32 | ++(define_cpu_unit "cva6_store" "cva6") |
| 33 | ++ |
| 34 | ++;; FPU and ALU2 units |
| 35 | ++(define_cpu_unit "cva6_fpu" "cva6") |
| 36 | ++(define_cpu_unit "cva6_alu2" "cva6") ;; if superscalar |
| 37 | ++ |
| 38 | ++;; ISSUE can be either ISSUE0 or ISSUE1 |
| 39 | ++(define_reservation "cva6_issue" "cva6_issue0|cva6_issue1") |
| 40 | ++ |
| 41 | ++;; ALU can be either ALU0 or ALU2, and ALU2 is preferred (if available) |
| 42 | ++(define_reservation "cva6_alu" "cva6_alu2|cva6_alu0") |
| 43 | ++ |
| 44 | ++;; Most (integer) instructions are dispatched to the ALUs |
| 45 | ++;; (All instructions need an issue port first) |
| 46 | ++(define_insn_reservation "cva6_int" 1 |
| 47 | ++ (and (eq_attr "tune" "cva6") |
| 48 | ++ (eq_attr "type" "const,arith,logical,shift,slt,move,fmove,auipc,nop,bitmanip,rotate,condmove")) |
| 49 | ++ "cva6_issue, cva6_alu") |
| 50 | ++;; ALU-ALU forwarding is possible between integer instructions |
| 51 | ++;;(define_bypass 0 "cva6_int" "cva6_int") |
| 52 | ++;; Actually disabled as it decreases performance for now |
| 53 | ++ |
| 54 | ++;; Branches/jumps/calls use the branch unit and the first ALU |
| 55 | ++(define_insn_reservation "cva6_branch" 1 |
| 56 | ++ (and (eq_attr "tune" "cva6") |
| 57 | ++ (eq_attr "type" "branch,jump,call")) |
| 58 | ++ "cva6_issue, cva6_branch+cva6_alu0") |
| 59 | ++;; When a branch is used, then the store unit is locked |
| 60 | ++(absence_set "cva6_store" "cva6_branch") |
| 61 | ++ |
| 62 | ++;; Multiplications use the multiplier, then the result bus of the ALU |
| 63 | ++(define_insn_reservation "cva6_mul" 2 ;; 2 cycles before the result is available |
| 64 | ++ (and (eq_attr "tune" "cva6") |
| 65 | ++ (eq_attr "type" "imul")) |
| 66 | ++ "cva6_issue, cva6_mul, cva6_alu0") |
| 67 | ++ |
| 68 | ++;; Divisions make the divider busy for a long time |
| 69 | ++(define_insn_reservation "cva6_div" 42 ;; FIXME use a realistic duration instead of 42 |
| 70 | ++ (and (eq_attr "tune" "cva6") |
| 71 | ++ (eq_attr "type" "idiv")) |
| 72 | ++ "cva6_issue, cva6_div*42") ;; FIXME use a realistic duration instead of 42 |
| 73 | ++;; FIXME the duration of the division can be XLEN-dependent |
| 74 | ++;; Using the divider prevents from using alu0 and mul (and vice versa) |
| 75 | ++(exclusion_set "cva6_div" "cva6_alu0,cva6_mul") |
| 76 | ++ |
| 77 | ++;; Unknown/custom and accelerator transfer instructions use CV-X-IF |
| 78 | ++(define_insn_reservation "cva6_cvxif" 1 ;; FIXME update duration |
| 79 | ++ (and (eq_attr "tune" "cva6") |
| 80 | ++ (eq_attr "type" "mfc,mtc,unknown,multi")) |
| 81 | ++ "cva6_issue, cva6_cvxif") |
| 82 | ++ |
| 83 | ++;; Load instructions, (int or float) use the load unit |
| 84 | ++(define_insn_reservation "cva6_load" 2 ;; latency = 2 cycles... |
| 85 | ++ (and (eq_attr "tune" "cva6") |
| 86 | ++ (eq_attr "type" "load,fpload")) |
| 87 | ++ "cva6_issue, cva6_load") ;; ... pipelined: unit busy for 1 cycle only |
| 88 | ++ |
| 89 | ++;; Store instructions, (int or float) use the store unit |
| 90 | ++(define_insn_reservation "cva6_store" 2 ;; latency = 2 cycles... |
| 91 | ++ (and (eq_attr "tune" "cva6") |
| 92 | ++ (eq_attr "type" "store,fpstore")) |
| 93 | ++ "cva6_issue, cva6_store") ;; ... pipelined: unit busy for 1 cycle only |
| 94 | ++;; Cannot use load and store units simultaneously |
| 95 | ++(exclusion_set "cva6_load" "cva6_store") |
| 96 | ++ |
| 97 | ++;; Floating point processing use the FPU for a long time |
| 98 | ++(define_insn_reservation "cva6_fp" 42 ;; FIXME use a realistic value instead of 42 |
| 99 | ++ (and (eq_attr "tune" "cva6") |
| 100 | ++ (eq_attr "type" "fadd,fmul,fmadd,fdiv,fcmp,fcvt,fsqrt")) |
| 101 | ++ "cva6_fpu*42") ;; FIXME use a realistic value instead of 42 |
| 102 | ++;; FIXME the duration of the FP ops can be XLEN-dependent |
| 103 | ++;; Using the FPU prevents from using alu2 (and vice versa) |
| 104 | ++(exclusion_set "cva6_fpu" "cva6_alu2") ;; if superscalar |
| 105 | ++ |
| 106 | ++;; FIXME define reservation for the following instructions: |
| 107 | ++;; sfb_alu atomic |
| 108 | +diff --git a/gcc/config/riscv/riscv-cores.def b/gcc/config/riscv/riscv-cores.def |
| 109 | +index 7d87ab7ce..b0993fd48 100644 |
| 110 | +--- a/gcc/config/riscv/riscv-cores.def |
| 111 | ++++ b/gcc/config/riscv/riscv-cores.def |
| 112 | +@@ -37,6 +37,7 @@ RISCV_TUNE("rocket", generic, rocket_tune_info) |
| 113 | + RISCV_TUNE("sifive-3-series", generic, rocket_tune_info) |
| 114 | + RISCV_TUNE("sifive-5-series", generic, rocket_tune_info) |
| 115 | + RISCV_TUNE("sifive-7-series", sifive_7, sifive_7_tune_info) |
| 116 | ++RISCV_TUNE("cva6", cva6, cva6_tune_info) |
| 117 | + RISCV_TUNE("thead-c906", generic, thead_c906_tune_info) |
| 118 | + RISCV_TUNE("size", generic, optimize_size_tune_info) |
| 119 | + |
| 120 | +diff --git a/gcc/config/riscv/riscv-opts.h b/gcc/config/riscv/riscv-opts.h |
| 121 | +index cf0cd669b..ff2a5ce33 100644 |
| 122 | +--- a/gcc/config/riscv/riscv-opts.h |
| 123 | ++++ b/gcc/config/riscv/riscv-opts.h |
| 124 | +@@ -52,7 +52,8 @@ extern enum riscv_isa_spec_class riscv_isa_spec; |
| 125 | + /* Keep this list in sync with define_attr "tune" in riscv.md. */ |
| 126 | + enum riscv_microarchitecture_type { |
| 127 | + generic, |
| 128 | +- sifive_7 |
| 129 | ++ sifive_7, |
| 130 | ++ cva6 |
| 131 | + }; |
| 132 | + extern enum riscv_microarchitecture_type riscv_microarchitecture; |
| 133 | + |
| 134 | +diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc |
| 135 | +index e88fa2d63..46a61b6b8 100644 |
| 136 | +--- a/gcc/config/riscv/riscv.cc |
| 137 | ++++ b/gcc/config/riscv/riscv.cc |
| 138 | +@@ -339,6 +339,20 @@ static const struct riscv_tune_param sifive_7_tune_info = { |
| 139 | + true, /* slow_unaligned_access */ |
| 140 | + }; |
| 141 | + |
| 142 | ++/* Costs to use when optimizing for CVA6. */ |
| 143 | ++static const struct riscv_tune_param cva6_tune_info = { |
| 144 | ++ {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_add */ |
| 145 | ++ {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_mul */ |
| 146 | ++ {COSTS_N_INSNS (20), COSTS_N_INSNS (20)}, /* fp_div */ |
| 147 | ++ {COSTS_N_INSNS (4), COSTS_N_INSNS (4)}, /* int_mul */ |
| 148 | ++ {COSTS_N_INSNS (6), COSTS_N_INSNS (6)}, /* int_div */ |
| 149 | ++ 2, /* issue_rate */ |
| 150 | ++ 6, /* branch_cost */ |
| 151 | ++ 2, /* memory_cost */ |
| 152 | ++ 8, /* fmv_cost */ |
| 153 | ++ false, /* slow_unaligned_access */ |
| 154 | ++}; |
| 155 | ++ |
| 156 | + /* Costs to use when optimizing for T-HEAD c906. */ |
| 157 | + static const struct riscv_tune_param thead_c906_tune_info = { |
| 158 | + {COSTS_N_INSNS (4), COSTS_N_INSNS (5)}, /* fp_add */ |
| 159 | +diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md |
| 160 | +index bc384d9ae..f4dacff34 100644 |
| 161 | +--- a/gcc/config/riscv/riscv.md |
| 162 | ++++ b/gcc/config/riscv/riscv.md |
| 163 | +@@ -437,7 +437,7 @@ |
| 164 | + ;; Microarchitectures we know how to tune for. |
| 165 | + ;; Keep this in sync with enum riscv_microarchitecture. |
| 166 | + (define_attr "tune" |
| 167 | +- "generic,sifive_7" |
| 168 | ++ "generic,sifive_7,cva6" |
| 169 | + (const (symbol_ref "((enum attr_tune) riscv_microarchitecture)"))) |
| 170 | + |
| 171 | + ;; Describe a user's asm statement. |
| 172 | +@@ -3145,5 +3145,6 @@ |
| 173 | + (include "pic.md") |
| 174 | + (include "generic.md") |
| 175 | + (include "sifive-7.md") |
| 176 | ++(include "cva6.md") |
| 177 | + (include "thead.md") |
| 178 | + (include "vector.md") |
0 commit comments