;; Scheduling description for PowerPC A2 processors.
;; Copyright (C) 2009-2017 Free Software Foundation, Inc.
;; Contributed by Ben Elliston (bje@au.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/>.

(define_automaton "ppca2")

;; CPU units

;; The multiplier pipeline.
(define_cpu_unit "mult" "ppca2")

;; The auxiliary processor unit (FP/vector unit).
(define_cpu_unit "axu" "ppca2")

;; D.4.6
;; Some peculiarities for certain SPRs

(define_insn_reservation "ppca2-mfcr" 1
  (and (eq_attr "type" "mfcr")
       (eq_attr "cpu" "ppca2"))
   "nothing")

(define_insn_reservation "ppca2-mfjmpr" 5
  (and (eq_attr "type" "mfjmpr")
       (eq_attr "cpu" "ppca2"))
  "nothing")

(define_insn_reservation "ppca2-mtjmpr" 5
  (and (eq_attr "type" "mtjmpr")
       (eq_attr "cpu" "ppca2"))
  "nothing")

;; D.4.8
(define_insn_reservation "ppca2-imul" 1
  (and (eq_attr "type" "mul")
       (eq_attr "size" "8,16,32")
       (eq_attr "cpu" "ppca2"))
  "nothing")

;; FIXME: latency and multiplier reservation for 64-bit multiply?
(define_insn_reservation "ppca2-lmul" 6
  (and (eq_attr "type" "mul")
       (eq_attr "size" "64")
       (eq_attr "cpu" "ppca2"))
  "mult*3")

;; D.4.9
(define_insn_reservation "ppca2-idiv" 32
  (and (eq_attr "type" "div")
       (eq_attr "size" "32")
       (eq_attr "cpu" "ppca2"))
  "mult*32")

(define_insn_reservation "ppca2-ldiv" 65
  (and (eq_attr "type" "div")
       (eq_attr "size" "64")
       (eq_attr "cpu" "ppca2"))
  "mult*65")

;; D.4.13
(define_insn_reservation "ppca2-load" 5
  (and (eq_attr "type" "load")
       (eq_attr "cpu" "ppca2"))
  "nothing")

;; D.8.1
(define_insn_reservation "ppca2-fp" 6
  (and (eq_attr "type" "fp,fpsimple")
       (eq_attr "cpu" "ppca2"))
  "axu")

;; D.8.4
(define_insn_reservation "ppca2-fp-load" 6
  (and (eq_attr "type" "fpload")
       (eq_attr "cpu" "ppca2"))
  "axu")

;; D.8.5
(define_insn_reservation "ppca2-fp-store" 2
  (and (eq_attr "type" "fpstore")
       (eq_attr "cpu" "ppca2"))
  "axu")

;; D.8.6
(define_insn_reservation "ppca2-fpcompare" 5
  (and (eq_attr "type" "fpcompare")
       (eq_attr "cpu" "ppca2"))
 "axu")

;; D.8.7
;;
;; Instructions from the same thread succeeding the floating-point
;; divide cannot be executed until the floating-point divide has
;; completed.  Since there is nothing else we can do, this thread will
;; just have to stall.

(define_insn_reservation "ppca2-ddiv" 72
  (and (eq_attr "type" "ddiv")
       (eq_attr "cpu" "ppca2"))
   "axu")

(define_insn_reservation "ppca2-sdiv" 59
  (and (eq_attr "type" "sdiv")
       (eq_attr "cpu" "ppca2"))
   "axu")

;; D.8.8
;; 
;; Instructions from the same thread succeeding the floating-point
;; divide cannot be executed until the floating-point divide has
;; completed.  Since there is nothing else we can do, this thread will
;; just have to stall.

(define_insn_reservation "ppca2-dsqrt" 69
  (and (eq_attr "type" "dsqrt")
       (eq_attr "cpu" "ppca2"))
  "axu")

(define_insn_reservation "ppca2-ssqrt" 65
  (and (eq_attr "type" "ssqrt")
       (eq_attr "cpu" "ppca2"))
  "axu")
