;; DFA scheduling description of the Synopsys DesignWare ARC HS4x cpu
;; for GNU C compiler
;; Copyright (C) 2017-2020 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 "ARCHS4x")
(define_cpu_unit "hs4x_issue0" "ARCHS4x")
(define_cpu_unit "hs4x_issue1" "ARCHS4x")
(define_cpu_unit "hs4x_ld_st" "ARCHS4x")
(define_cpu_unit "hs4x_divrem" "ARCHS4x")
(define_cpu_unit "hs4x_mult" "ARCHS4x")
(define_cpu_unit "hs4x_x1, hs4x_x2" "ARCHS4x")
(define_cpu_unit "hs4x_y1, hs4x_y2" "ARCHS4x")
(define_insn_reservation "hs4x_brj_op" 1
(and (match_test "TARGET_HS")
(eq_attr "tune" "archs4x, archs4xd")
(eq_attr "type" "call, call_no_delay_slot, uncond_branch, jump, \
branch, brcc,brcc_no_delay_slot, sfunc"))
"hs4x_issue0")
(define_insn_reservation "hs4x_data_load_op" 4
(and (match_test "TARGET_HS")
(eq_attr "tune" "archs4x, archs4xd")
(eq_attr "type" "load"))
"hs4x_issue1 + hs4x_ld_st,hs4x_ld_st")
(define_insn_reservation "hs4x_data_store_op" 1
(and (match_test "TARGET_HS")
(eq_attr "tune" "archs4x, archs4xd")
(eq_attr "type" "store"))
"hs4x_issue1 + hs4x_ld_st")
;; Advanced ALU
(define_insn_reservation "hs4x_adv_alue_op" 4
(and (match_test "TARGET_HS")
(eq_attr "tune" "archs4x, archs4xd")
(eq_attr "type" "cc_arith, two_cycle_core, shift, lr, sr"))
"(hs4x_issue0 | hs4x_issue1), hs4x_x1")
(define_insn_reservation "hs4x_adv_alul_op" 6
(and (match_test "TARGET_HS")
(eq_attr "tune" "archs4xd")
(eq_attr "type" "cc_arith, two_cycle_core, shift, lr, sr"))
"(hs4x_issue0 | hs4x_issue1), nothing*2, hs4x_x2")
;; Basic ALU
(define_insn_reservation "hs4x_basic_alue_op" 1
(and (match_test "TARGET_HS")
(eq_attr "tune" "archs4x, archs4xd")
(eq_attr "type" "move, cmove, unary, binary, compare, misc"))
"(hs4x_issue0 | hs4x_issue1) + hs4x_y1")
(define_insn_reservation "hs4x_basic_alul_op" 4
(and (match_test "TARGET_HS")
(eq_attr "tune" "archs4x, archs4xd")
(eq_attr "type" "move, cmove, unary, binary, compare, misc"))
"(hs4x_issue0 | hs4x_issue1), nothing*2, hs4x_y2")
(define_insn_reservation "hs4x_divrem_op" 13
(and (match_test "TARGET_HS")
(eq_attr "tune" "archs4x, archs4xd")
(eq_attr "type" "div_rem"))
"hs4x_issue0 + hs4x_divrem, (hs4x_divrem)*12")
;;Consider the DSPMPY fast here
(define_insn_reservation "hs4x_mul_fast_op" 7
(and (match_test "TARGET_HS")
(eq_attr "tune_dspmpy" "fast")
(eq_attr "type" "mul16_em, multi, umulti"))
"hs4x_issue0 + hs4x_mult")
(define_insn_reservation "hs4x_mul_slow_op" 8
(and (match_test "TARGET_HS")
(eq_attr "tune_dspmpy" "slow")
(eq_attr "type" "mul16_em, multi, umulti"))
"hs4x_issue0 + hs4x_mult")
;; FPU unit
(define_insn_reservation "hs4x_fpu_op" 8
(and (match_test "TARGET_HS")
(eq_attr "tune" "archs4x, archs4xd")
(eq_attr "type" "fpu"))
"hs4x_issue0")
;; FPU FUSE unit
(define_insn_reservation "hs4x_fpu_fuse_op" 12
(and (match_test "TARGET_HS")
(eq_attr "tune" "archs4x, archs4xd")
(eq_attr "type" "fpu_fuse"))
"hs4x_issue0")
;; FPU SP SQRT/DIV unit
(define_insn_reservation "hs4x_fpu_sdiv_op" 20
(and (match_test "TARGET_HS")
(eq_attr "tune" "archs4x, archs4xd")
(eq_attr "type" "fpu_sdiv"))
"hs4x_issue0")
;; FPU DP SQRT/DIV unit
(define_insn_reservation "hs4x_fpu_ddiv_op" 34
(and (match_test "TARGET_HS")
(eq_attr "tune" "archs4x, archs4xd")
(eq_attr "type" "fpu_ddiv"))
"hs4x_issue0")
;; FPU CVT unit
(define_insn_reservation "hs4x_fpu_cvt_op" 5
(and (match_test "TARGET_HS")
(eq_attr "tune" "archs4x, archs4xd")
(eq_attr "type" "fpu_cvt"))
"hs4x_issue0")
;; BYPASS Advanced ALU ->
(define_bypass 1 "hs4x_adv_alue_op" "hs4x_divrem_op")
(define_bypass 1 "hs4x_adv_alue_op" "hs4x_mul_*op")
(define_bypass 2 "hs4x_adv_alue_op" "hs4x_adv_alue_op")
(define_bypass 1 "hs4x_adv_alue_op" "hs4x_basic_alue_op")
(define_bypass 1 "hs4x_adv_alue_op" "hs4x_basic_alul_op")
(define_bypass 1 "hs4x_adv_alue_op" "hs4x_data_load_op")
(define_bypass 0 "hs4x_adv_alue_op" "hs4x_data_store_op" "store_data_bypass_p")
(define_bypass 2 "hs4x_adv_alue_op" "hs4x_data_store_op")
(define_bypass 1 "hs4x_adv_alue_op" "hs4x_fpu_*op")
(define_bypass 2 "hs4x_adv_alul_op" "hs4x_basic_alul_op")
(define_bypass 2 "hs4x_adv_alul_op" "hs4x_adv_alul_op")
(define_bypass 2 "hs4x_adv_alul_op" "hs4x_mul_*op")
(define_bypass 0 "hs4x_adv_alul_op" "hs4x_data_store_op" "store_data_bypass_p")
(define_bypass 4 "hs4x_adv_alul_op" "hs4x_divrem_op")
(define_bypass 5 "hs4x_adv_alul_op" "hs4x_fpu_*op")
;; BYPASS Basic ALU ->
(define_bypass 0 "hs4x_basic_alue_op" "hs4x_data_store_op" "store_data_bypass_p")
(define_bypass 1 "hs4x_basic_alul_op" "hs4x_basic_alul_op")
(define_bypass 1 "hs4x_basic_alul_op" "hs4x_adv_alul_op")
(define_bypass 0 "hs4x_basic_alul_op" "hs4x_data_store_op" "store_data_bypass_p")
(define_bypass 1 "hs4x_basic_alul_op" "hs4x_mul_*op")
(define_bypass 3 "hs4x_basic_alul_op" "hs4x_divrem_op")
(define_bypass 3 "hs4x_basic_alul_op" "hs4x_fpu_*op")
;; BYPASS LD ->
(define_bypass 1 "hs4x_data_load_op" "hs4x_basic_alul_op")
(define_bypass 1 "hs4x_data_load_op" "hs4x_adv_alul_op")
(define_bypass 3 "hs4x_data_load_op" "hs4x_divrem_op")
(define_bypass 3 "hs4x_data_load_op" "hs4x_data_load_op")
(define_bypass 3 "hs4x_data_load_op" "hs4x_mul_*op")
(define_bypass 0 "hs4x_data_load_op" "hs4x_data_store_op" "store_data_bypass_p")
(define_bypass 3 "hs4x_data_load_op" "hs4x_fpu_*op")
;; BYPASS FAST MPY ->
(define_bypass 4 "hs4x_mul_fast_op" "hs4x_basic_alul_op")
(define_bypass 4 "hs4x_mul_fast_op" "hs4x_adv_alul_op")
(define_bypass 4 "hs4x_mul_fast_op" "hs4x_mul_fast_op")
(define_bypass 6 "hs4x_mul_fast_op" "hs4x_divrem_op")
(define_bypass 0 "hs4x_mul_fast_op" "hs4x_data_store_op" "store_data_bypass_p")
(define_bypass 6 "hs4x_mul_fast_op" "hs4x_fpu_*op")
;; BYPASS SLOW MPY ->
(define_bypass 5 "hs4x_mul_slow_op" "hs4x_basic_alul_op")
(define_bypass 5 "hs4x_mul_slow_op" "hs4x_adv_alul_op")
(define_bypass 5 "hs4x_mul_slow_op" "hs4x_mul_slow_op")
(define_bypass 7 "hs4x_mul_slow_op" "hs4x_divrem_op")
(define_bypass 0 "hs4x_mul_slow_op" "hs4x_data_store_op" "store_data_bypass_p")
(define_bypass 7 "hs4x_mul_slow_op" "hs4x_fpu_*op")
;;BYPASS FPU ->
(define_bypass 5 "hs4x_fpu_op" "hs4x_basic_alul_op")
(define_bypass 5 "hs4x_fpu_op" "hs4x_adv_alul_op")
(define_bypass 5 "hs4x_fpu_op" "hs4x_mul_*op")
(define_bypass 7 "hs4x_fpu_op" "hs4x_divrem_op")
(define_bypass 5 "hs4x_fpu_op" "hs4x_fpu_*op")
(define_bypass 0 "hs4x_fpu_op" "hs4x_data_store_op" "store_data_bypass_p")
;;BYPASS FPU FUSE ->
(define_bypass 9 "hs4x_fpu_fuse_op" "hs4x_basic_alul_op")
(define_bypass 9 "hs4x_fpu_fuse_op" "hs4x_adv_alul_op")
(define_bypass 9 "hs4x_fpu_fuse_op" "hs4x_mul_*op")
(define_bypass 11 "hs4x_fpu_fuse_op" "hs4x_divrem_op")
(define_bypass 11 "hs4x_fpu_fuse_op" "hs4x_fpu_*op")
(define_bypass 0 "hs4x_fpu_fuse_op" "hs4x_data_store_op" "store_data_bypass_p")
;;BYPASS FPU SP DIV ->
(define_bypass 16 "hs4x_fpu_sdiv_op" "hs4x_basic_alul_op")
(define_bypass 16 "hs4x_fpu_sdiv_op" "hs4x_adv_alul_op")
(define_bypass 16 "hs4x_fpu_sdiv_op" "hs4x_mul_*op")
(define_bypass 19 "hs4x_fpu_sdiv_op" "hs4x_divrem_op")
(define_bypass 19 "hs4x_fpu_sdiv_op" "hs4x_fpu_*op")
(define_bypass 0 "hs4x_fpu_sdiv_op" "hs4x_data_store_op" "store_data_bypass_p")
;;BYPASS FPU DP DIV ->
(define_bypass 31 "hs4x_fpu_ddiv_op" "hs4x_basic_alul_op")
(define_bypass 31 "hs4x_fpu_ddiv_op" "hs4x_adv_alul_op")
(define_bypass 31 "hs4x_fpu_ddiv_op" "hs4x_mul_*op")
(define_bypass 34 "hs4x_fpu_ddiv_op" "hs4x_divrem_op")
(define_bypass 34 "hs4x_fpu_ddiv_op" "hs4x_fpu_*op")
(define_bypass 0 "hs4x_fpu_ddiv_op" "hs4x_data_store_op" "store_data_bypass_p")
;;BYPASS FPU CVT ->
(define_bypass 1 "hs4x_fpu_cvt_op" "hs4x_basic_alul_op")
(define_bypass 1 "hs4x_fpu_cvt_op" "hs4x_adv_alul_op")
(define_bypass 1 "hs4x_fpu_cvt_op" "hs4x_mul_*op")
(define_bypass 4 "hs4x_fpu_cvt_op" "hs4x_divrem_op")
(define_bypass 4 "hs4x_fpu_cvt_op" "hs4x_fpu_*op")
(define_bypass 0 "hs4x_fpu_cvt_op" "hs4x_data_store_op" "store_data_bypass_p")