;; Scheduling description for the IBM POWER10 processor. ;; Copyright (C) 2020-2021 Free Software Foundation, Inc. ;; ;; Contributed by Pat Haugen (pthaugen@us.ibm.com).

;; 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/.

; For Power10 we model (and try to pack) the in-order decode/dispatch groups ; which consist of 8 instructions max. We do not try to model the details of ; the out-of-order issue queues and how insns flow to the various execution ; units except for the simple representation of the issue limitation of at ; most 4 insns to the execution units/2 insns to the load units/2 insns to ; the store units. (define_automaton “power10dispatch,power10issue”)

; Decode/dispatch slots (define_cpu_unit “du0_power10,du1_power10,du2_power10,du3_power10, du4_power10,du5_power10,du6_power10,du7_power10” “power10dispatch”)

; Four execution units (define_cpu_unit “exu0_power10,exu1_power10,exu2_power10,exu3_power10” “power10issue”) ; Two load units and two store units (define_cpu_unit “lu0_power10,lu1_power10” “power10issue”) (define_cpu_unit “stu0_power10,stu1_power10” “power10issue”)

; Dispatch slots are allocated in order conforming to program order. (absence_set “du0_power10” “du1_power10,du2_power10,du3_power10,du4_power10,
du5_power10,du6_power10,du7_power10”) (absence_set “du1_power10” “du2_power10,du3_power10,du4_power10,du5_power10,
du6_power10,du7_power10”) (absence_set “du2_power10” “du3_power10,du4_power10,du5_power10,du6_power10,
du7_power10”) (absence_set “du3_power10” “du4_power10,du5_power10,du6_power10,du7_power10”) (absence_set “du4_power10” “du5_power10,du6_power10,du7_power10”) (absence_set “du5_power10” “du6_power10,du7_power10”) (absence_set “du6_power10” “du7_power10”)

; Dispatch port reservations ; ; Power10 can dispatch a maximum of 8 iops per cycle. With a maximum of ; 4 VSU/2 Load/2 Store per cycle.

; Any dispatch slot (define_reservation “DU_any_power10” “du0_power10|du1_power10|du2_power10|du3_power10| du4_power10|du5_power10|du6_power10|du7_power10”)

; Even slot, actually takes even/odd slots (define_reservation “DU_even_power10” “du0_power10+du1_power10|du2_power10+du3_power10| du4_power10+du5_power10|du6_power10+du7_power10”)

; 4-way cracked (consumes whole decode/dispatch cycle) (define_reservation “DU_all_power10” “du0_power10+du1_power10+du2_power10+du3_power10+ du4_power10+du5_power10+du6_power10+du7_power10”)

; Execution unit reservations (define_reservation “LU_power10” “lu0_power10|lu1_power10”)

(define_reservation “STU_power10” “stu0_power10|stu1_power10”)

; Certain simple fixed-point insns can execute in the Store-agen pipe (define_reservation “SXU_power10” “stu0_power10|stu1_power10”)

(define_reservation “EXU_power10” “exu0_power10|exu1_power10|exu2_power10|exu3_power10”)

(define_reservation “EXU_super_power10” “exu0_power10+exu1_power10|exu2_power10+exu3_power10”)

; Load Unit (define_insn_reservation “power10-load” 4 (and (eq_attr “type” “load”) (eq_attr “update” “no”) (eq_attr “size” “!128”) (eq_attr “prefixed” “no”) (eq_attr “cpu” “power10”)) “DU_any_power10,LU_power10”)

(define_insn_reservation “power10-fused-load” 4 (and (eq_attr “type” “fused_load_cmpi,fused_addis_load,fused_load_load”) (eq_attr “cpu” “power10”)) “DU_even_power10,LU_power10”)

(define_insn_reservation “power10-prefixed-load” 4 (and (eq_attr “type” “load”) (eq_attr “update” “no”) (eq_attr “size” “!128”) (eq_attr “prefixed” “yes”) (eq_attr “cpu” “power10”)) “DU_even_power10,LU_power10”)

(define_insn_reservation “power10-load-update” 4 (and (eq_attr “type” “load”) (eq_attr “update” “yes”) (eq_attr “cpu” “power10”)) “DU_even_power10,LU_power10+SXU_power10”)

(define_insn_reservation “power10-fpload-double” 4 (and (eq_attr “type” “fpload”) (eq_attr “update” “no”) (eq_attr “size” “64”) (eq_attr “prefixed” “no”) (eq_attr “cpu” “power10”)) “DU_any_power10,LU_power10”)

(define_insn_reservation “power10-prefixed-fpload-double” 4 (and (eq_attr “type” “fpload”) (eq_attr “update” “no”) (eq_attr “size” “64”) (eq_attr “prefixed” “yes”) (eq_attr “cpu” “power10”)) “DU_even_power10,LU_power10”)

(define_insn_reservation “power10-fpload-update-double” 4 (and (eq_attr “type” “fpload”) (eq_attr “update” “yes”) (eq_attr “size” “64”) (eq_attr “cpu” “power10”)) “DU_even_power10,LU_power10+SXU_power10”)

; SFmode loads are cracked and have additional 3 cycles over DFmode ; Prefixed forms behave the same (define_insn_reservation “power10-fpload-single” 7 (and (eq_attr “type” “fpload”) (eq_attr “update” “no”) (eq_attr “size” “32”) (eq_attr “cpu” “power10”)) “DU_even_power10,LU_power10”)

(define_insn_reservation “power10-fpload-update-single” 7 (and (eq_attr “type” “fpload”) (eq_attr “update” “yes”) (eq_attr “size” “32”) (eq_attr “cpu” “power10”)) “DU_even_power10,LU_power10+SXU_power10”)

(define_insn_reservation “power10-vecload” 4 (and (eq_attr “type” “vecload”) (eq_attr “size” “!256”) (eq_attr “cpu” “power10”)) “DU_any_power10,LU_power10”)

; lxvp (define_insn_reservation “power10-vecload-pair” 4 (and (eq_attr “type” “vecload”) (eq_attr “size” “256”) (eq_attr “cpu” “power10”)) “DU_even_power10,LU_power10+SXU_power10”)

; Store Unit (define_insn_reservation “power10-store” 0 (and (eq_attr “type” “store,fpstore,vecstore”) (eq_attr “update” “no”) (eq_attr “prefixed” “no”) (eq_attr “size” “!128”) (eq_attr “size” “!256”) (eq_attr “cpu” “power10”)) “DU_any_power10,STU_power10”)

(define_insn_reservation “power10-fused-store” 0 (and (eq_attr “type” “fused_store_store”) (eq_attr “cpu” “power10”)) “DU_even_power10,STU_power10”)

(define_insn_reservation “power10-prefixed-store” 0 (and (eq_attr “type” “store,fpstore,vecstore”) (eq_attr “prefixed” “yes”) (eq_attr “size” “!128”) (eq_attr “size” “!256”) (eq_attr “cpu” “power10”)) “DU_even_power10,STU_power10”)

; Update forms have 2 cycle latency for updated addr reg (define_insn_reservation “power10-store-update” 2 (and (eq_attr “type” “store,fpstore”) (eq_attr “update” “yes”) (eq_attr “cpu” “power10”)) “DU_any_power10,STU_power10”)

; stxvp (define_insn_reservation “power10-vecstore-pair” 0 (and (eq_attr “type” “vecstore”) (eq_attr “size” “256”) (eq_attr “cpu” “power10”)) “DU_even_power10,stu0_power10+stu1_power10”)

(define_insn_reservation “power10-larx” 4 (and (eq_attr “type” “load_l”) (eq_attr “size” “!128”) (eq_attr “cpu” “power10”)) “DU_any_power10,LU_power10”)

; All load quad forms (define_insn_reservation “power10-lq” 4 (and (eq_attr “type” “load,load_l”) (eq_attr “size” “128”) (eq_attr “cpu” “power10”)) “DU_even_power10,LU_power10+SXU_power10”)

(define_insn_reservation “power10-stcx” 0 (and (eq_attr “type” “store_c”) (eq_attr “size” “!128”) (eq_attr “cpu” “power10”)) “DU_any_power10,STU_power10”)

; All store quad forms (define_insn_reservation “power10-stq” 0 (and (eq_attr “type” “store,store_c”) (eq_attr “size” “128”) (eq_attr “cpu” “power10”)) “DU_even_power10,stu0_power10+stu1_power10”)

(define_insn_reservation “power10-sync” 1 (and (eq_attr “type” “sync,isync”) (eq_attr “cpu” “power10”)) “DU_even_power10,STU_power10”)

; VSU Execution Unit

; Fixed point ops

; Most ALU insns are simple 2 cycle, including record form (define_insn_reservation “power10-alu” 2 (and (eq_attr “type” “add,exts,integer,logical,isel”) (eq_attr “prefixed” “no”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”) ; 4 cycle CR latency (define_bypass 4 “power10-alu” “power10-crlogical,power10-mfcr,power10-mfcrf”)

(define_insn_reservation “power10-fused_alu” 2 (and (eq_attr “type” “fused_arith_logical,fused_cmp_isel,fused_carry”) (eq_attr “cpu” “power10”)) “DU_even_power10,EXU_power10”)

; paddi (define_insn_reservation “power10-paddi” 2 (and (eq_attr “type” “add”) (eq_attr “prefixed” “yes”) (eq_attr “cpu” “power10”)) “DU_even_power10,EXU_power10”)

; Rotate/shift (non-record form) (define_insn_reservation “power10-rot” 2 (and (eq_attr “type” “insert,shift”) (eq_attr “dot” “no”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”)

; Record form rotate/shift (define_insn_reservation “power10-rot-compare” 3 (and (eq_attr “type” “insert,shift”) (eq_attr “dot” “yes”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”) ; 5 cycle CR latency (define_bypass 5 “power10-rot-compare” “power10-crlogical,power10-mfcr,power10-mfcrf”)

(define_insn_reservation “power10-alu2” 3 (and (eq_attr “type” “cntlz,popcnt,trap”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”) ; 5 cycle CR latency (define_bypass 5 “power10-alu2” “power10-crlogical,power10-mfcr,power10-mfcrf”)

(define_insn_reservation “power10-cmp” 2 (and (eq_attr “type” “cmp”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”)

; Treat ‘two’ and ‘three’ types as 2 or 3 way cracked (define_insn_reservation “power10-two” 4 (and (eq_attr “type” “two”) (eq_attr “cpu” “power10”)) “DU_even_power10,EXU_power10”)

(define_insn_reservation “power10-three” 6 (and (eq_attr “type” “three”) (eq_attr “cpu” “power10”)) “DU_all_power10,EXU_power10”)

(define_insn_reservation “power10-mul” 5 (and (eq_attr “type” “mul”) (eq_attr “dot” “no”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”) ; 4 cycle MUL->MUL latency (define_bypass 4 “power10-mul” “power10-mul,power10-mul-compare”)

(define_insn_reservation “power10-mul-compare” 5 (and (eq_attr “type” “mul”) (eq_attr “dot” “yes”) (eq_attr “cpu” “power10”)) “DU_even_power10,EXU_power10”) ; 4 cycle MUL->MUL latency (define_bypass 4 “power10-mul-compare” “power10-mul,power10-mul-compare”) ; 7 cycle CR latency (define_bypass 7 “power10-mul-compare” “power10-crlogical,power10-mfcr,power10-mfcrf”)

(define_insn_reservation “power10-div” 12 (and (eq_attr “type” “div”) (eq_attr “dot” “no”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”)

(define_insn_reservation “power10-div-compare” 12 (and (eq_attr “type” “div”) (eq_attr “dot” “yes”) (eq_attr “cpu” “power10”)) “DU_even_power10,EXU_power10”) ; 14 cycle CR latency (define_bypass 14 “power10-div-compare” “power10-crlogical,power10-mfcr,power10-mfcrf”)

(define_insn_reservation “power10-crlogical” 2 (and (eq_attr “type” “cr_logical”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”)

(define_insn_reservation “power10-mfcrf” 2 (and (eq_attr “type” “mfcrf”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”)

(define_insn_reservation “power10-mfcr” 3 (and (eq_attr “type” “mfcr”) (eq_attr “cpu” “power10”)) “DU_even_power10,EXU_power10”)

; Should differentiate between 1 cr field and > 1 since target of > 1 cr ; is cracked (define_insn_reservation “power10-mtcr” 3 (and (eq_attr “type” “mtcr”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”)

(define_insn_reservation “power10-mtjmpr” 3 (and (eq_attr “type” “mtjmpr”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”)

(define_insn_reservation “power10-mfjmpr” 2 (and (eq_attr “type” “mfjmpr”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”)

; Floating point/Vector ops

(define_insn_reservation “power10-fpsimple” 3 (and (eq_attr “type” “fpsimple”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”)

(define_insn_reservation “power10-fp” 5 (and (eq_attr “type” “fp,dmul”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”)

(define_insn_reservation “power10-fpcompare” 3 (and (eq_attr “type” “fpcompare”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”)

(define_insn_reservation “power10-sdiv” 22 (and (eq_attr “type” “sdiv”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”)

(define_insn_reservation “power10-ddiv” 27 (and (eq_attr “type” “ddiv”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”)

(define_insn_reservation “power10-sqrt” 26 (and (eq_attr “type” “ssqrt”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”)

(define_insn_reservation “power10-dsqrt” 36 (and (eq_attr “type” “dsqrt”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”)

(define_insn_reservation “power10-vec-2cyc” 2 (and (eq_attr “type” “vecmove,veclogical,vecexts,veccmpfx”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”)

(define_insn_reservation “power10-fused-vec” 2 (and (eq_attr “type” “fused_vector”) (eq_attr “cpu” “power10”)) “DU_even_power10,EXU_power10”)

(define_insn_reservation “power10-veccmp” 3 (and (eq_attr “type” “veccmp”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”)

(define_insn_reservation “power10-vecsimple” 2 (and (eq_attr “type” “vecsimple”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”)

(define_insn_reservation “power10-vecnormal” 5 (and (eq_attr “type” “vecfloat,vecdouble”) (eq_attr “size” “!128”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”)

(define_insn_reservation “power10-qp” 12 (and (eq_attr “type” “vecfloat,vecdouble”) (eq_attr “size” “128”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”)

(define_insn_reservation “power10-vecperm” 3 (and (eq_attr “type” “vecperm”) (eq_attr “prefixed” “no”) (eq_attr “dot” “no”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”)

(define_insn_reservation “power10-vecperm-compare” 3 (and (eq_attr “type” “vecperm”) (eq_attr “dot” “yes”) (eq_attr “cpu” “power10”)) “DU_even_power10,EXU_power10”)

(define_insn_reservation “power10-prefixed-vecperm” 3 (and (eq_attr “type” “vecperm”) (eq_attr “prefixed” “yes”) (eq_attr “cpu” “power10”)) “DU_even_power10,EXU_power10”)

(define_insn_reservation “power10-veccomplex” 6 (and (eq_attr “type” “veccomplex”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”)

(define_insn_reservation “power10-vecfdiv” 24 (and (eq_attr “type” “vecfdiv”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”)

(define_insn_reservation “power10-vecdiv” 27 (and (eq_attr “type” “vecdiv”) (eq_attr “size” “!128”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”)

(define_insn_reservation “power10-qpdiv” 56 (and (eq_attr “type” “vecdiv”) (eq_attr “size” “128”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”)

(define_insn_reservation “power10-qpmul” 24 (and (eq_attr “type” “qmul”) (eq_attr “size” “128”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”)

(define_insn_reservation “power10-mtvsr” 2 (and (eq_attr “type” “mtvsr”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”)

(define_insn_reservation “power10-mfvsr” 2 (and (eq_attr “type” “mfvsr”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”)

; Branch ; Branch is 2 cycles, grouped with STU for issue (define_insn_reservation “power10-branch” 2 (and (eq_attr “type” “jmpreg,branch”) (eq_attr “cpu” “power10”)) “DU_any_power10,STU_power10”)

(define_insn_reservation “power10-fused-branch” 3 (and (eq_attr “type” “fused_mtbc”) (eq_attr “cpu” “power10”)) “DU_even_power10,STU_power10”)

; Crypto (define_insn_reservation “power10-crypto” 4 (and (eq_attr “type” “crypto”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”)

; HTM (define_insn_reservation “power10-htm” 2 (and (eq_attr “type” “htmsimple,htm”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”)

; DFP ; Use the minimum 12 cycle latency for all DFP insns (define_insn_reservation “power10-dfp” 12 (and (eq_attr “type” “dfp”) (eq_attr “size” “!128”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_power10”)

(define_insn_reservation “power10-dfpq” 12 (and (eq_attr “type” “dfp”) (eq_attr “size” “128”) (eq_attr “cpu” “power10”)) “DU_even_power10,EXU_power10”)

; MMA (define_insn_reservation “power10-mma” 9 (and (eq_attr “type” “mma”) (eq_attr “prefixed” “no”) (eq_attr “cpu” “power10”)) “DU_any_power10,EXU_super_power10”)

(define_insn_reservation “power10-prefixed-mma” 9 (and (eq_attr “type” “mma”) (eq_attr “prefixed” “yes”) (eq_attr “cpu” “power10”)) “DU_even_power10,EXU_super_power10”) ; 4 cycle MMA->MMA latency (define_bypass 4 “power10-mma,power10-prefixed-mma” “power10-mma,power10-prefixed-mma”)