1;; Pipeline descriptions of Andes NDS32 cpu for GNU compiler 2;; Copyright (C) 2012-2021 Free Software Foundation, Inc. 3;; Contributed by Andes Technology Corporation. 4;; 5;; This file is part of GCC. 6;; 7;; GCC is free software; you can redistribute it and/or modify it 8;; under the terms of the GNU General Public License as published 9;; by the Free Software Foundation; either version 3, or (at your 10;; option) any later version. 11;; 12;; GCC is distributed in the hope that it will be useful, but WITHOUT 13;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15;; License for more details. 16;; 17;; You should have received a copy of the GNU General Public License 18;; along with GCC; see the file COPYING3. If not see 19;; <http://www.gnu.org/licenses/>. 20 21 22;; ------------------------------------------------------------------------ 23;; Define N8 pipeline settings. 24;; ------------------------------------------------------------------------ 25 26(define_automaton "nds32_n8_machine") 27 28;; ------------------------------------------------------------------------ 29;; Pipeline Stages 30;; ------------------------------------------------------------------------ 31;; IF - Instruction Fetch 32;; II - Instruction Issue / Address Generation 33;; EX - Instruction Execution 34;; EXD - Psuedo Stage / Load Data Completion 35 36(define_cpu_unit "n8_ii" "nds32_n8_machine") 37(define_cpu_unit "n8_ex" "nds32_n8_machine") 38 39(define_insn_reservation "nds_n8_unknown" 1 40 (and (eq_attr "type" "unknown") 41 (eq_attr "pipeline_model" "n8")) 42 "n8_ii, n8_ex") 43 44(define_insn_reservation "nds_n8_misc" 1 45 (and (eq_attr "type" "misc") 46 (eq_attr "pipeline_model" "n8")) 47 "n8_ii, n8_ex") 48 49(define_insn_reservation "nds_n8_alu" 1 50 (and (eq_attr "type" "alu") 51 (eq_attr "pipeline_model" "n8")) 52 "n8_ii, n8_ex") 53 54(define_insn_reservation "nds_n8_load" 1 55 (and (match_test "nds32::load_single_p (insn)") 56 (eq_attr "pipeline_model" "n8")) 57 "n8_ii, n8_ex") 58 59(define_insn_reservation "nds_n8_store" 1 60 (and (match_test "nds32::store_single_p (insn)") 61 (eq_attr "pipeline_model" "n8")) 62 "n8_ii, n8_ex") 63 64(define_insn_reservation "nds_n8_load_multiple_1" 1 65 (and (and (eq_attr "type" "load_multiple") 66 (eq_attr "combo" "1")) 67 (eq_attr "pipeline_model" "n8")) 68 "n8_ii, n8_ex") 69 70(define_insn_reservation "nds_n8_load_multiple_2" 1 71 (and (ior (and (eq_attr "type" "load_multiple") 72 (eq_attr "combo" "2")) 73 (match_test "nds32::load_double_p (insn)")) 74 (eq_attr "pipeline_model" "n8")) 75 "n8_ii, n8_ii+n8_ex, n8_ex") 76 77(define_insn_reservation "nds_n8_load_multiple_3" 1 78 (and (and (eq_attr "type" "load_multiple") 79 (eq_attr "combo" "3")) 80 (eq_attr "pipeline_model" "n8")) 81 "n8_ii, (n8_ii+n8_ex)*2, n8_ex") 82 83(define_insn_reservation "nds_n8_load_multiple_4" 1 84 (and (and (eq_attr "type" "load_multiple") 85 (eq_attr "combo" "4")) 86 (eq_attr "pipeline_model" "n8")) 87 "n8_ii, (n8_ii+n8_ex)*3, n8_ex") 88 89(define_insn_reservation "nds_n8_load_multiple_5" 1 90 (and (and (eq_attr "type" "load_multiple") 91 (eq_attr "combo" "5")) 92 (eq_attr "pipeline_model" "n8")) 93 "n8_ii, (n8_ii+n8_ex)*4, n8_ex") 94 95(define_insn_reservation "nds_n8_load_multiple_6" 1 96 (and (and (eq_attr "type" "load_multiple") 97 (eq_attr "combo" "6")) 98 (eq_attr "pipeline_model" "n8")) 99 "n8_ii, (n8_ii+n8_ex)*5, n8_ex") 100 101(define_insn_reservation "nds_n8_load_multiple_7" 1 102 (and (and (eq_attr "type" "load_multiple") 103 (eq_attr "combo" "7")) 104 (eq_attr "pipeline_model" "n8")) 105 "n8_ii, (n8_ii+n8_ex)*6, n8_ex") 106 107(define_insn_reservation "nds_n8_load_multiple_8" 1 108 (and (and (eq_attr "type" "load_multiple") 109 (eq_attr "combo" "8")) 110 (eq_attr "pipeline_model" "n8")) 111 "n8_ii, (n8_ii+n8_ex)*7, n8_ex") 112 113(define_insn_reservation "nds_n8_load_multiple_12" 1 114 (and (and (eq_attr "type" "load_multiple") 115 (eq_attr "combo" "12")) 116 (eq_attr "pipeline_model" "n8")) 117 "n8_ii, (n8_ii+n8_ex)*11, n8_ex") 118 119(define_insn_reservation "nds_n8_store_multiple_1" 1 120 (and (and (eq_attr "type" "store_multiple") 121 (eq_attr "combo" "1")) 122 (eq_attr "pipeline_model" "n8")) 123 "n8_ii, n8_ex") 124 125(define_insn_reservation "nds_n8_store_multiple_2" 1 126 (and (ior (and (eq_attr "type" "store_multiple") 127 (eq_attr "combo" "2")) 128 (match_test "nds32::store_double_p (insn)")) 129 (eq_attr "pipeline_model" "n8")) 130 "n8_ii, n8_ii+n8_ex, n8_ex") 131 132(define_insn_reservation "nds_n8_store_multiple_3" 1 133 (and (and (eq_attr "type" "store_multiple") 134 (eq_attr "combo" "3")) 135 (eq_attr "pipeline_model" "n8")) 136 "n8_ii, (n8_ii+n8_ex)*2, n8_ex") 137 138(define_insn_reservation "nds_n8_store_multiple_4" 1 139 (and (and (eq_attr "type" "store_multiple") 140 (eq_attr "combo" "4")) 141 (eq_attr "pipeline_model" "n8")) 142 "n8_ii, (n8_ii+n8_ex)*3, n8_ex") 143 144(define_insn_reservation "nds_n8_store_multiple_5" 1 145 (and (and (eq_attr "type" "store_multiple") 146 (eq_attr "combo" "5")) 147 (eq_attr "pipeline_model" "n8")) 148 "n8_ii, (n8_ii+n8_ex)*4, n8_ex") 149 150(define_insn_reservation "nds_n8_store_multiple_6" 1 151 (and (and (eq_attr "type" "store_multiple") 152 (eq_attr "combo" "6")) 153 (eq_attr "pipeline_model" "n8")) 154 "n8_ii, (n8_ii+n8_ex)*5, n8_ex") 155 156(define_insn_reservation "nds_n8_store_multiple_7" 1 157 (and (and (eq_attr "type" "store_multiple") 158 (eq_attr "combo" "7")) 159 (eq_attr "pipeline_model" "n8")) 160 "n8_ii, (n8_ii+n8_ex)*6, n8_ex") 161 162(define_insn_reservation "nds_n8_store_multiple_8" 1 163 (and (and (eq_attr "type" "store_multiple") 164 (eq_attr "combo" "8")) 165 (eq_attr "pipeline_model" "n8")) 166 "n8_ii, (n8_ii+n8_ex)*7, n8_ex") 167 168(define_insn_reservation "nds_n8_store_multiple_12" 1 169 (and (and (eq_attr "type" "store_multiple") 170 (eq_attr "combo" "12")) 171 (eq_attr "pipeline_model" "n8")) 172 "n8_ii, (n8_ii+n8_ex)*11, n8_ex") 173 174(define_insn_reservation "nds_n8_mul_fast" 1 175 (and (match_test "nds32_mul_config != MUL_TYPE_SLOW") 176 (and (eq_attr "type" "mul") 177 (eq_attr "pipeline_model" "n8"))) 178 "n8_ii, n8_ex") 179 180(define_insn_reservation "nds_n8_mul_slow" 1 181 (and (match_test "nds32_mul_config == MUL_TYPE_SLOW") 182 (and (eq_attr "type" "mul") 183 (eq_attr "pipeline_model" "n8"))) 184 "n8_ii, n8_ex*16") 185 186(define_insn_reservation "nds_n8_mac_fast" 1 187 (and (match_test "nds32_mul_config != MUL_TYPE_SLOW") 188 (and (eq_attr "type" "mac") 189 (eq_attr "pipeline_model" "n8"))) 190 "n8_ii, n8_ii+n8_ex, n8_ex") 191 192(define_insn_reservation "nds_n8_mac_slow" 1 193 (and (match_test "nds32_mul_config == MUL_TYPE_SLOW") 194 (and (eq_attr "type" "mac") 195 (eq_attr "pipeline_model" "n8"))) 196 "n8_ii, (n8_ii+n8_ex)*16, n8_ex") 197 198(define_insn_reservation "nds_n8_div" 1 199 (and (eq_attr "type" "div") 200 (eq_attr "pipeline_model" "n8")) 201 "n8_ii, (n8_ii+n8_ex)*36, n8_ex") 202 203(define_insn_reservation "nds_n8_branch" 1 204 (and (eq_attr "type" "branch") 205 (eq_attr "pipeline_model" "n8")) 206 "n8_ii, n8_ex") 207 208;; ------------------------------------------------------------------------ 209;; Comment Notations and Bypass Rules 210;; ------------------------------------------------------------------------ 211;; Producers (LHS) 212;; LD_!bi 213;; Load data from the memory (without updating the base register) and 214;; produce the loaded data. The result is ready at EXD. 215;; LD_bi 216;; Load data from the memory (with updating the base register) and 217;; produce the loaded data. The result is ready at EXD. Because the 218;; register port is 2R1W, two micro-operations are required in order 219;; to write two registers. The base register is updated by the second 220;; micro-operation and the result is ready at EX. 221;; LMW(N, M) 222;; There are N micro-operations within an instruction that loads multiple 223;; words. The result produced by the M-th micro-operation is sent to 224;; consumers. The result is ready at EXD. If the base register should be 225;; updated, an extra micro-operation is inserted to the sequence, and the 226;; result is ready at EX. 227;; ADDR_OUT 228;; Most load/store instructions can produce an address output if updating 229;; the base register is required. The result is ready at EX, which is 230;; produced by ALU. 231;; ALU, MUL, MAC 232;; The result is ready at EX. 233;; MOVD44_O 234;; A double-word move instruction needs to write registers twice. Because 235;; the register port is 2R1W, two micro-operations are required. The even 236;; number reigster is updated by the first one, and the odd number register 237;; is updated by the second one. Each of the results is ready at EX. 238;; The letter 'O' stands for odd. 239;; DIV_Rs 240;; A division instruction saves the quotient result to Rt and saves the 241;; remainder result to Rs. It requires two micro-operations because the 242;; register port is 2R1W. The first micro-operation writes to Rt, and 243;; the seconde one writes to Rs. Each of the results is ready at EX. 244;; 245;; Consumers (RHS) 246;; ALU, MUL, DIV 247;; Require operands at EX. 248;; MOVD44_E 249;; The letter 'E' stands for even, which is accessed by the first micro- 250;; operation and a movd44 instruction. The operand is required at EX. 251;; MAC_RaRb 252;; A MAC instruction is separated into two micro-operations. The first 253;; micro-operation does the multiplication, which requires operands Ra 254;; and Rb at EX. The second micro-options does the accumulation, which 255;; requires the operand Rt at EX. 256;; ADDR_IN_MOP(N) 257;; Because the reigster port is 2R1W, some load/store instructions are 258;; separated into many micro-operations. N denotes the address input is 259;; required by the N-th micro-operation. Such operand is required at II. 260;; ST_bi 261;; A post-increment store instruction requires its data at EX. 262;; ST_!bi_RI 263;; A store instruction with an immediate offset requires its data at EX. 264;; If the offset field is a register (ST_!bi_RR), the instruction will be 265;; separated into two micro-operations, and the second one requires the 266;; input operand at EX in order to store it to the memory. 267;; SMW(N, M) 268;; There are N micro-operations within an instruction that stores multiple 269;; words. Each M-th micro-operation requires its data at EX. If the base 270;; register should be updated, an extra micro-operation is inserted to the 271;; sequence. 272;; BR_COND 273;; If a branch instruction is conditional, its input data is required at EX. 274 275;; LD_!bi -> ADDR_IN_MOP(1) 276(define_bypass 3 277 "nds_n8_load" 278 "nds_n8_branch,\ 279 nds_n8_load, nds_n8_store,\ 280 nds_n8_load_multiple_1,nds_n8_load_multiple_2, nds_n8_load_multiple_3,\ 281 nds_n8_load_multiple_4,nds_n8_load_multiple_5, nds_n8_load_multiple_6,\ 282 nds_n8_load_multiple_7,nds_n8_load_multiple_8, nds_n8_load_multiple_12,\ 283 nds_n8_store_multiple_1,nds_n8_store_multiple_2, nds_n8_store_multiple_3,\ 284 nds_n8_store_multiple_4,nds_n8_store_multiple_5, nds_n8_store_multiple_6,\ 285 nds_n8_store_multiple_7,nds_n8_store_multiple_8, nds_n8_store_multiple_12" 286 "nds32_n8_load_to_ii_p" 287) 288 289;; LMW(N, N) -> ADDR_IN_MOP(1) 290(define_bypass 3 291 "nds_n8_load_multiple_1,nds_n8_load_multiple_2, nds_n8_load_multiple_3,\ 292 nds_n8_load_multiple_4,nds_n8_load_multiple_5, nds_n8_load_multiple_6,\ 293 nds_n8_load_multiple_7,nds_n8_load_multiple_8, nds_n8_load_multiple_12" 294 "nds_n8_branch,\ 295 nds_n8_load, nds_n8_store,\ 296 nds_n8_load_multiple_1,nds_n8_load_multiple_2, nds_n8_load_multiple_3,\ 297 nds_n8_load_multiple_4,nds_n8_load_multiple_5, nds_n8_load_multiple_6,\ 298 nds_n8_load_multiple_7,nds_n8_load_multiple_8, nds_n8_load_multiple_12,\ 299 nds_n8_store_multiple_1,nds_n8_store_multiple_2, nds_n8_store_multiple_3,\ 300 nds_n8_store_multiple_4,nds_n8_store_multiple_5, nds_n8_store_multiple_6,\ 301 nds_n8_store_multiple_7,nds_n8_store_multiple_8, nds_n8_store_multiple_12" 302 "nds32_n8_last_load_to_ii_p" 303) 304 305;; LMW(N, N - 1) -> ADDR_IN_MOP(1) 306(define_bypass 2 307 "nds_n8_load_multiple_1,nds_n8_load_multiple_2, nds_n8_load_multiple_3,\ 308 nds_n8_load_multiple_4,nds_n8_load_multiple_5, nds_n8_load_multiple_6,\ 309 nds_n8_load_multiple_7,nds_n8_load_multiple_8, nds_n8_load_multiple_12" 310 "nds_n8_branch,\ 311 nds_n8_load, nds_n8_store,\ 312 nds_n8_load_multiple_1,nds_n8_load_multiple_2, nds_n8_load_multiple_3,\ 313 nds_n8_load_multiple_4,nds_n8_load_multiple_5, nds_n8_load_multiple_6,\ 314 nds_n8_load_multiple_7,nds_n8_load_multiple_8, nds_n8_load_multiple_12,\ 315 nds_n8_store_multiple_1,nds_n8_store_multiple_2, nds_n8_store_multiple_3,\ 316 nds_n8_store_multiple_4,nds_n8_store_multiple_5, nds_n8_store_multiple_6,\ 317 nds_n8_store_multiple_7,nds_n8_store_multiple_8, nds_n8_store_multiple_12" 318 "nds32_n8_last_load_two_to_ii_p" 319) 320 321;; LD_bi -> ADDR_IN_MOP(1) 322(define_bypass 2 323 "nds_n8_load" 324 "nds_n8_branch,\ 325 nds_n8_load, nds_n8_store,\ 326 nds_n8_load_multiple_1,nds_n8_load_multiple_2, nds_n8_load_multiple_3,\ 327 nds_n8_load_multiple_4,nds_n8_load_multiple_5, nds_n8_load_multiple_6,\ 328 nds_n8_load_multiple_7,nds_n8_load_multiple_8, nds_n8_load_multiple_12,\ 329 nds_n8_store_multiple_1,nds_n8_store_multiple_2, nds_n8_store_multiple_3,\ 330 nds_n8_store_multiple_4,nds_n8_store_multiple_5, nds_n8_store_multiple_6,\ 331 nds_n8_store_multiple_7,nds_n8_store_multiple_8, nds_n8_store_multiple_12" 332 "nds32_n8_load_bi_to_ii_p" 333) 334 335;; LD_!bi -> ALU, MOVD44_E, MUL, MAC_RaRb, DIV, BR_COND, ST_bi, ST_!bi_RI, SMW(N, 1) 336(define_bypass 2 337 "nds_n8_load" 338 "nds_n8_alu, 339 nds_n8_mul_fast, nds_n8_mul_slow,\ 340 nds_n8_mac_fast, nds_n8_mac_slow,\ 341 nds_n8_div,\ 342 nds_n8_branch,\ 343 nds_n8_store,\ 344 nds_n8_store_multiple_1,nds_n8_store_multiple_2, nds_n8_store_multiple_3,\ 345 nds_n8_store_multiple_4,nds_n8_store_multiple_5, nds_n8_store_multiple_6,\ 346 nds_n8_store_multiple_7,nds_n8_store_multiple_8, nds_n8_store_multiple_12" 347 "nds32_n8_load_to_ex_p" 348) 349 350;; ALU, MOVD44_O, MUL, MAC, DIV_Rs, LD_bi, ADDR_OUT -> ADDR_IN_MOP(1) 351(define_bypass 2 352 "nds_n8_alu, 353 nds_n8_mul_fast, nds_n8_mul_slow,\ 354 nds_n8_mac_fast, nds_n8_mac_slow,\ 355 nds_n8_div,\ 356 nds_n8_load, nds_n8_store,\ 357 nds_n8_load_multiple_1,nds_n8_load_multiple_2, nds_n8_load_multiple_3,\ 358 nds_n8_load_multiple_4,nds_n8_load_multiple_5, nds_n8_load_multiple_6,\ 359 nds_n8_load_multiple_7,nds_n8_load_multiple_8, nds_n8_load_multiple_12,\ 360 nds_n8_store_multiple_1,nds_n8_store_multiple_2, nds_n8_store_multiple_3,\ 361 nds_n8_store_multiple_4,nds_n8_store_multiple_5, nds_n8_store_multiple_6,\ 362 nds_n8_store_multiple_7,nds_n8_store_multiple_8, nds_n8_store_multiple_12" 363 "nds_n8_branch,\ 364 nds_n8_load, nds_n8_store,\ 365 nds_n8_load_multiple_1,nds_n8_load_multiple_2, nds_n8_load_multiple_3,\ 366 nds_n8_load_multiple_4,nds_n8_load_multiple_5, nds_n8_load_multiple_6,\ 367 nds_n8_load_multiple_7,nds_n8_load_multiple_8, nds_n8_load_multiple_12,\ 368 nds_n8_store_multiple_1,nds_n8_store_multiple_2, nds_n8_store_multiple_3,\ 369 nds_n8_store_multiple_4,nds_n8_store_multiple_5, nds_n8_store_multiple_6,\ 370 nds_n8_store_multiple_7,nds_n8_store_multiple_8, nds_n8_store_multiple_12" 371 "nds32_n8_ex_to_ii_p" 372) 373 374;; LMW(N, N) -> ALU, MOVD44_E, MUL, MAC_RaRb, DIV, BR_COND, ST_bi, ST_!bi_RI, SMW(N, 1) 375(define_bypass 2 376 "nds_n8_load_multiple_1,nds_n8_load_multiple_2, nds_n8_load_multiple_3,\ 377 nds_n8_load_multiple_4,nds_n8_load_multiple_5, nds_n8_load_multiple_6,\ 378 nds_n8_load_multiple_7,nds_n8_load_multiple_8, nds_n8_load_multiple_12" 379 "nds_n8_alu, 380 nds_n8_mul_fast, nds_n8_mul_slow,\ 381 nds_n8_mac_fast, nds_n8_mac_slow,\ 382 nds_n8_div,\ 383 nds_n8_branch,\ 384 nds_n8_store,\ 385 nds_n8_store_multiple_1,nds_n8_store_multiple_2, nds_n8_store_multiple_3,\ 386 nds_n8_store_multiple_4,nds_n8_store_multiple_5, nds_n8_store_multiple_6,\ 387 nds_n8_store_multiple_7,nds_n8_store_multiple_8, nds_n8_store_multiple_12" 388 "nds32_n8_last_load_to_ex_p" 389) 390