| ;; DFA-based pipeline description for the RM7000. |
| ;; Copyright (C) 2003-2026 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/>. |
| |
| ;; ......................... |
| ;; |
| ;; The RM7000 is a dual-issue processor that can bundle instructions as: |
| ;; {arith|load|store}{arith|imul|idiv|branch|float} |
| ;; |
| ;; Reference: |
| ;; "RM7000 Family User Manual, PMC-2002296" |
| ;; |
| ;; ......................... |
| |
| ;; Use three automata to isolate long latency operations, reducing space. |
| (define_automaton "rm7000_other, rm7000_fdiv, rm7000_idiv") |
| |
| ;; |
| ;; Describe the resources. |
| ;; |
| |
| ;; Global |
| (define_cpu_unit "rm7_iss0,rm7_iss1" "rm7000_other") |
| |
| ;; Integer execution unit (M-Pipe). |
| (define_cpu_unit "ixum_addsub_agen" "rm7000_other") |
| |
| ;; Integer execution unit (F-Pipe). |
| (define_cpu_unit "ixuf_addsub" "rm7000_other") |
| (define_cpu_unit "ixuf_branch" "rm7000_other") |
| (define_cpu_unit "ixuf_mpydiv" "rm7000_other") |
| (define_cpu_unit "ixuf_mpydiv_iter" "rm7000_idiv") |
| ;; Floating-point unit (F-Pipe). |
| (define_cpu_unit "fxuf_add" "rm7000_other") |
| (define_cpu_unit "fxuf_mpy" "rm7000_other") |
| (define_cpu_unit "fxuf_mpy_iter" "rm7000_fdiv") |
| (define_cpu_unit "fxuf_divsqrt" "rm7000_other") |
| (define_cpu_unit "fxuf_divsqrt_iter" "rm7000_fdiv") |
| |
| (exclusion_set "ixuf_addsub" |
| "ixuf_branch,ixuf_mpydiv,fxuf_add,fxuf_mpy,fxuf_divsqrt") |
| (exclusion_set "ixuf_branch" "ixuf_mpydiv,fxuf_add,fxuf_mpy,fxuf_divsqrt") |
| (exclusion_set "ixuf_mpydiv" "fxuf_add,fxuf_mpy,fxuf_divsqrt") |
| (exclusion_set "fxuf_add" "fxuf_mpy,fxuf_divsqrt") |
| (exclusion_set "fxuf_mpy" "fxuf_divsqrt") |
| |
| ;; After branch any insn cannot be issued. |
| (absence_set "rm7_iss0,rm7_iss1" "ixuf_branch") |
| |
| ;; |
| ;; Define reservations for unit name mnemonics or combinations. |
| ;; |
| |
| (define_reservation "rm7_iss" "rm7_iss0|rm7_iss1") |
| (define_reservation "rm7_single_dispatch" "rm7_iss0+rm7_iss1") |
| |
| (define_reservation "rm7_iaddsub" "rm7_iss+(ixum_addsub_agen|ixuf_addsub)") |
| (define_reservation "rm7_imem" "rm7_iss+ixum_addsub_agen") |
| (define_reservation "rm7_impydiv" "rm7_iss+ixuf_mpydiv") |
| (define_reservation "rm7_impydiv_iter" "ixuf_mpydiv_iter") |
| (define_reservation "rm7_branch" "rm7_iss+ixuf_branch") |
| |
| (define_reservation "rm7_fpadd" "rm7_iss+fxuf_add") |
| (define_reservation "rm7_fpmpy" "rm7_iss+fxuf_mpy") |
| (define_reservation "rm7_fpmpy_iter" "fxuf_mpy_iter") |
| (define_reservation "rm7_fpdivsqr" "rm7_iss+fxuf_divsqrt") |
| (define_reservation "rm7_fpdivsqr_iter" "fxuf_divsqrt_iter") |
| |
| ;; |
| ;; Describe instruction reservations for integer operations. |
| ;; |
| |
| (define_insn_reservation "rm7_int_other" 1 |
| (and (eq_attr "cpu" "r7000") |
| (eq_attr "type" "arith,shift,signext,slt,clz,const,condmove,logical,move,nop,trap")) |
| "rm7_iaddsub") |
| |
| (define_insn_reservation "rm7_ld" 2 |
| (and (eq_attr "cpu" "r7000") |
| (eq_attr "type" "load,fpload,fpidxload")) |
| "rm7_imem") |
| |
| (define_insn_reservation "rm7_st" 1 |
| (and (eq_attr "cpu" "r7000") |
| (eq_attr "type" "store,fpstore,fpidxstore")) |
| "rm7_imem") |
| |
| (define_insn_reservation "rm7_idiv_si" 36 |
| (and (eq_attr "cpu" "r7000") |
| (and (eq_attr "type" "idiv") |
| (eq_attr "mode" "SI"))) |
| "rm7_impydiv+(rm7_impydiv_iter*36)") |
| |
| (define_insn_reservation "rm7_idiv_di" 68 |
| (and (eq_attr "cpu" "r7000") |
| (and (eq_attr "type" "idiv") |
| (eq_attr "mode" "DI"))) |
| "rm7_impydiv+(rm7_impydiv_iter*68)") |
| |
| (define_insn_reservation "rm7_impy_si_mult" 5 |
| (and (eq_attr "cpu" "r7000") |
| (and (eq_attr "type" "imul,imadd") |
| (eq_attr "mode" "SI"))) |
| "rm7_impydiv+(rm7_impydiv_iter*3)") |
| |
| ;; There are an additional 2 stall cycles. |
| (define_insn_reservation "rm7_impy_si_mul" 2 |
| (and (eq_attr "cpu" "r7000") |
| (and (eq_attr "type" "imul3") |
| (eq_attr "mode" "SI"))) |
| "rm7_impydiv") |
| |
| (define_insn_reservation "rm7_impy_di" 9 |
| (and (eq_attr "cpu" "r7000") |
| (and (eq_attr "type" "imul,imul3") |
| (eq_attr "mode" "DI"))) |
| "rm7_impydiv+(rm7_impydiv_iter*8)") |
| |
| ;; Move to/from HI/LO. |
| (define_insn_reservation "rm7_mthilo" 3 |
| (and (eq_attr "cpu" "r7000") |
| (eq_attr "type" "mthi,mtlo")) |
| "rm7_impydiv") |
| |
| (define_insn_reservation "rm7_mfhilo" 1 |
| (and (eq_attr "cpu" "r7000") |
| (eq_attr "type" "mfhi,mflo")) |
| "rm7_impydiv") |
| |
| ;; Move to/from fp coprocessor. |
| (define_insn_reservation "rm7_ixfer" 2 |
| (and (eq_attr "cpu" "r7000") |
| (eq_attr "type" "mfc,mtc")) |
| "rm7_iaddsub") |
| |
| (define_insn_reservation "rm7_ibr" 3 |
| (and (eq_attr "cpu" "r7000") |
| (eq_attr "type" "branch,jump,call")) |
| "rm7_branch") |
| |
| ;; |
| ;; Describe instruction reservations for the floating-point operations. |
| ;; |
| (define_insn_reservation "rm7_fp_quick" 4 |
| (and (eq_attr "cpu" "r7000") |
| (eq_attr "type" "fneg,fcmp,fabs,fmove")) |
| "rm7_fpadd") |
| |
| (define_insn_reservation "rm7_fp_other" 4 |
| (and (eq_attr "cpu" "r7000") |
| (eq_attr "type" "fadd")) |
| "rm7_fpadd") |
| |
| (define_insn_reservation "rm7_fp_cvt" 4 |
| (and (eq_attr "cpu" "r7000") |
| (eq_attr "type" "fcvt")) |
| "rm7_fpadd") |
| |
| (define_insn_reservation "rm7_fp_divsqrt_df" 36 |
| (and (eq_attr "cpu" "r7000") |
| (and (eq_attr "type" "fdiv,frdiv,fsqrt") |
| (eq_attr "mode" "DF"))) |
| "rm7_fpdivsqr+(rm7_fpdivsqr_iter*36)") |
| |
| (define_insn_reservation "rm7_fp_divsqrt_sf" 21 |
| (and (eq_attr "cpu" "r7000") |
| (and (eq_attr "type" "fdiv,frdiv,fsqrt") |
| (eq_attr "mode" "SF"))) |
| "rm7_fpdivsqr+(rm7_fpdivsqr_iter*21)") |
| |
| (define_insn_reservation "rm7_fp_rsqrt_df" 68 |
| (and (eq_attr "cpu" "r7000") |
| (and (eq_attr "type" "frsqrt") |
| (eq_attr "mode" "DF"))) |
| "rm7_fpdivsqr+(rm7_fpdivsqr_iter*68)") |
| |
| (define_insn_reservation "rm7_fp_rsqrt_sf" 38 |
| (and (eq_attr "cpu" "r7000") |
| (and (eq_attr "type" "frsqrt") |
| (eq_attr "mode" "SF"))) |
| "rm7_fpdivsqr+(rm7_fpdivsqr_iter*38)") |
| |
| (define_insn_reservation "rm7_fp_mpy_sf" 4 |
| (and (eq_attr "cpu" "r7000") |
| (and (eq_attr "type" "fmul,fmadd") |
| (eq_attr "mode" "SF"))) |
| "rm7_fpmpy+rm7_fpmpy_iter") |
| |
| (define_insn_reservation "rm7_fp_mpy_df" 5 |
| (and (eq_attr "cpu" "r7000") |
| (and (eq_attr "type" "fmul,fmadd") |
| (eq_attr "mode" "DF"))) |
| "rm7_fpmpy+(rm7_fpmpy_iter*2)") |
| |
| ;; Force single-dispatch for unknown or multi. |
| (define_insn_reservation "rm7_unknown" 1 |
| (and (eq_attr "cpu" "r7000") |
| (eq_attr "type" "unknown,multi,atomic,syncloop")) |
| "rm7_single_dispatch") |