aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/config/arm/cortex-a7.md
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9/gcc/config/arm/cortex-a7.md')
-rw-r--r--gcc-4.9/gcc/config/arm/cortex-a7.md394
1 files changed, 394 insertions, 0 deletions
diff --git a/gcc-4.9/gcc/config/arm/cortex-a7.md b/gcc-4.9/gcc/config/arm/cortex-a7.md
new file mode 100644
index 000000000..8291d7fa9
--- /dev/null
+++ b/gcc-4.9/gcc/config/arm/cortex-a7.md
@@ -0,0 +1,394 @@
+;; ARM Cortex-A7 pipeline description
+;; Copyright (C) 2012-2014 Free Software Foundation, Inc.
+;;
+;; Contributed by ARM Ltd.
+;; Based on cortex-a5.md which was originally contributed by CodeSourcery.
+;;
+;; 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_attr "cortex_a7_neon_type"
+ "neon_mul, neon_mla, neon_other"
+ (cond [
+ (eq_attr "type" "neon_mul_b, neon_mul_b_q,\
+ neon_mul_h, neon_mul_h_q,\
+ neon_mul_s, neon_mul_s_q,\
+ neon_mul_b_long, neon_mul_h_long,\
+ neon_mul_s_long, neon_mul_h_scalar,\
+ neon_mul_h_scalar_q, neon_mul_s_scalar,\
+ neon_mul_s_scalar_q, neon_mul_h_scalar_long,\
+ neon_mul_s_scalar_long,\
+ neon_sat_mul_b, neon_sat_mul_b_q,\
+ neon_sat_mul_h, neon_sat_mul_h_q,\
+ neon_sat_mul_s, neon_sat_mul_s_q,\
+ neon_sat_mul_b_long, neon_sat_mul_h_long,\
+ neon_sat_mul_s_long,\
+ neon_sat_mul_h_scalar, neon_sat_mul_h_scalar_q,\
+ neon_sat_mul_s_scalar, neon_sat_mul_s_scalar_q,\
+ neon_sat_mul_h_scalar_long,\
+ neon_sat_mul_s_scalar_long,\
+ neon_fp_mul_s, neon_fp_mul_s_q,\
+ neon_fp_mul_s_scalar, neon_fp_mul_s_scalar_q")
+ (const_string "neon_mul")
+ (eq_attr "type" "neon_mla_b, neon_mla_b_q, neon_mla_h,\
+ neon_mla_h_q, neon_mla_s, neon_mla_s_q,\
+ neon_mla_b_long, neon_mla_h_long,\
+ neon_mla_s_long,\
+ neon_mla_h_scalar, neon_mla_h_scalar_q,\
+ neon_mla_s_scalar, neon_mla_s_scalar_q,\
+ neon_mla_h_scalar_long, neon_mla_s_scalar_long,\
+ neon_sat_mla_b_long, neon_sat_mla_h_long,\
+ neon_sat_mla_s_long,\
+ neon_sat_mla_h_scalar_long,\
+ neon_sat_mla_s_scalar_long,\
+ neon_fp_mla_s, neon_fp_mla_s_q,\
+ neon_fp_mla_s_scalar, neon_fp_mla_s_scalar_q")
+ (const_string "neon_mla")]
+ (const_string "neon_other")))
+
+(define_automaton "cortex_a7")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Functional units.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; The Cortex-A7 pipeline integer and vfp pipeline.
+;; The decode is the same for all instructions, so do not model it.
+;; We only model the first execution stage because
+;; instructions always advance one stage per cycle in order.
+;; We model all of the LS, Branch, ALU, MAC and FPU pipelines together.
+
+(define_cpu_unit "cortex_a7_ex1, cortex_a7_ex2" "cortex_a7")
+
+(define_reservation "cortex_a7_both" "cortex_a7_ex1+cortex_a7_ex2")
+
+(define_cpu_unit "cortex_a7_branch" "cortex_a7")
+
+;; Cortex-A7 is in order and can dual-issue under limited circumstances.
+;; ex2 can be reserved only after ex1 is reserved.
+
+(final_presence_set "cortex_a7_ex2" "cortex_a7_ex1")
+
+;; Pseudo-unit for blocking the multiply pipeline when a double-precision
+;; multiply is in progress.
+
+(define_cpu_unit "cortex_a7_fpmul_pipe" "cortex_a7")
+
+;; The floating-point add pipeline (ex1/f1 stage), used to model the usage
+;; of the add pipeline by fmac instructions, etc.
+
+(define_cpu_unit "cortex_a7_fpadd_pipe" "cortex_a7")
+
+;; Floating-point div/sqrt (long latency, out-of-order completion).
+
+(define_cpu_unit "cortex_a7_fp_div_sqrt" "cortex_a7")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Branches.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; A direct branch can dual issue either as younger or older instruction,
+;; but branches cannot dual issue with branches.
+;; No latency as there is no result.
+
+(define_insn_reservation "cortex_a7_branch" 0
+ (and (eq_attr "tune" "cortexa7")
+ (eq_attr "type" "branch"))
+ "(cortex_a7_ex2|cortex_a7_ex1)+cortex_a7_branch")
+
+;; Call cannot dual-issue as an older instruction. It can dual-issue
+;; as a younger instruction, or single-issue. Call cannot dual-issue
+;; with another branch instruction. The result is available the next
+;; cycle.
+(define_insn_reservation "cortex_a7_call" 1
+ (and (eq_attr "tune" "cortexa7")
+ (eq_attr "type" "call"))
+ "(cortex_a7_ex2|cortex_a7_both)+cortex_a7_branch")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; ALU instructions.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; ALU instruction with an immediate operand can dual-issue.
+(define_insn_reservation "cortex_a7_alu_imm" 2
+ (and (eq_attr "tune" "cortexa7")
+ (ior (eq_attr "type" "adr,alu_imm,alus_imm,logic_imm,logics_imm,\
+ mov_imm,mvn_imm,extend")
+ (and (eq_attr "type" "mov_reg,mov_shift,mov_shift_reg")
+ (not (eq_attr "length" "8")))))
+ "cortex_a7_ex2|cortex_a7_ex1")
+
+;; ALU instruction with register operands can dual-issue
+;; with a younger immediate-based instruction.
+(define_insn_reservation "cortex_a7_alu_reg" 2
+ (and (eq_attr "tune" "cortexa7")
+ (eq_attr "type" "alu_reg,alus_reg,logic_reg,logics_reg,\
+ adc_imm,adcs_imm,adc_reg,adcs_reg,\
+ bfm,rev,\
+ shift_imm,shift_reg,mov_reg,mvn_reg"))
+ "cortex_a7_ex1")
+
+(define_insn_reservation "cortex_a7_alu_shift" 2
+ (and (eq_attr "tune" "cortexa7")
+ (eq_attr "type" "alu_shift_imm,alus_shift_imm,\
+ logic_shift_imm,logics_shift_imm,\
+ alu_shift_reg,alus_shift_reg,\
+ logic_shift_reg,logics_shift_reg,\
+ mov_shift,mov_shift_reg,\
+ mvn_shift,mvn_shift_reg,\
+ mrs,multiple,no_insn"))
+ "cortex_a7_ex1")
+
+;; Forwarding path for unshifted operands.
+(define_bypass 1 "cortex_a7_alu_imm,cortex_a7_alu_reg,cortex_a7_alu_shift"
+ "cortex_a7_alu_imm,cortex_a7_alu_reg,cortex_a7_mul")
+
+(define_bypass 1 "cortex_a7_alu_imm,cortex_a7_alu_reg,cortex_a7_alu_shift"
+ "cortex_a7_store*"
+ "arm_no_early_store_addr_dep")
+
+(define_bypass 1 "cortex_a7_alu_imm,cortex_a7_alu_reg,cortex_a7_alu_shift"
+ "cortex_a7_alu_shift"
+ "arm_no_early_alu_shift_dep")
+
+;; The multiplier pipeline can forward results from wr stage only so
+;; there's no need to specify bypasses.
+;; Multiply instructions cannot dual-issue.
+
+(define_insn_reservation "cortex_a7_mul" 2
+ (and (eq_attr "tune" "cortexa7")
+ (ior (eq_attr "mul32" "yes")
+ (eq_attr "mul64" "yes")))
+ "cortex_a7_both")
+
+;; Forward the result of a multiply operation to the accumulator
+;; of the following multiply and accumulate instruction.
+(define_bypass 1 "cortex_a7_mul"
+ "cortex_a7_mul"
+ "arm_mac_accumulator_is_result")
+
+;; The latency depends on the operands, so we use an estimate here.
+(define_insn_reservation "cortex_a7_idiv" 5
+ (and (eq_attr "tune" "cortexa7")
+ (eq_attr "type" "udiv,sdiv"))
+ "cortex_a7_both*5")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Load/store instructions.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Address-generation happens in the issue stage.
+;; Double-word accesses can be issued in a single cycle,
+;; and occupy only one pipeline stage.
+
+(define_insn_reservation "cortex_a7_load1" 2
+ (and (eq_attr "tune" "cortexa7")
+ (eq_attr "type" "load_byte,load1"))
+ "cortex_a7_ex1")
+
+(define_insn_reservation "cortex_a7_store1" 0
+ (and (eq_attr "tune" "cortexa7")
+ (eq_attr "type" "store1"))
+ "cortex_a7_ex1")
+
+(define_insn_reservation "cortex_a7_load2" 2
+ (and (eq_attr "tune" "cortexa7")
+ (eq_attr "type" "load2"))
+ "cortex_a7_both")
+
+(define_insn_reservation "cortex_a7_store2" 0
+ (and (eq_attr "tune" "cortexa7")
+ (eq_attr "type" "store2"))
+ "cortex_a7_both")
+
+(define_insn_reservation "cortex_a7_load3" 3
+ (and (eq_attr "tune" "cortexa7")
+ (eq_attr "type" "load3"))
+ "cortex_a7_both, cortex_a7_ex1")
+
+(define_insn_reservation "cortex_a7_store3" 0
+ (and (eq_attr "tune" "cortexa7")
+ (eq_attr "type" "store4"))
+ "cortex_a7_both, cortex_a7_ex1")
+
+(define_insn_reservation "cortex_a7_load4" 3
+ (and (eq_attr "tune" "cortexa7")
+ (eq_attr "type" "load4"))
+ "cortex_a7_both, cortex_a7_both")
+
+(define_insn_reservation "cortex_a7_store4" 0
+ (and (eq_attr "tune" "cortexa7")
+ (eq_attr "type" "store3"))
+ "cortex_a7_both, cortex_a7_both")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Floating-point arithmetic.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Neon integer, neon floating point, and single-precision floating
+;; point instructions of the same type have the same timing
+;; characteristics, but neon instructions cannot dual-issue.
+
+(define_insn_reservation "cortex_a7_fpalu" 4
+ (and (eq_attr "tune" "cortexa7")
+ (eq_attr "type" "ffariths, fadds, ffarithd, faddd, fmov,\
+ f_cvt, f_cvtf2i, f_cvti2f, fcmps, fcmpd"))
+ "cortex_a7_ex1+cortex_a7_fpadd_pipe")
+
+;; For fconsts and fconstd, 8-bit immediate data is passed directly from
+;; f1 to f3 (which I think reduces the latency by one cycle).
+
+(define_insn_reservation "cortex_a7_fconst" 3
+ (and (eq_attr "tune" "cortexa7")
+ (eq_attr "type" "fconsts,fconstd"))
+ "cortex_a7_ex1+cortex_a7_fpadd_pipe")
+
+;; We should try not to attempt to issue a single-precision multiplication in
+;; the middle of a double-precision multiplication operation (the usage of
+;; cortex_a7_fpmul_pipe).
+
+(define_insn_reservation "cortex_a7_fpmuls" 4
+ (and (eq_attr "tune" "cortexa7")
+ (eq_attr "type" "fmuls"))
+ "cortex_a7_ex1+cortex_a7_fpmul_pipe")
+
+(define_insn_reservation "cortex_a7_neon_mul" 4
+ (and (eq_attr "tune" "cortexa7")
+ (eq_attr "cortex_a7_neon_type" "neon_mul"))
+ "(cortex_a7_both+cortex_a7_fpmul_pipe)*2")
+
+(define_insn_reservation "cortex_a7_fpmacs" 8
+ (and (eq_attr "tune" "cortexa7")
+ (eq_attr "type" "fmacs,ffmas"))
+ "cortex_a7_ex1+cortex_a7_fpmul_pipe")
+
+(define_insn_reservation "cortex_a7_neon_mla" 8
+ (and (eq_attr "tune" "cortexa7")
+ (eq_attr "cortex_a7_neon_type" "neon_mla"))
+ "cortex_a7_both+cortex_a7_fpmul_pipe")
+
+(define_bypass 4 "cortex_a7_fpmacs,cortex_a7_neon_mla"
+ "cortex_a7_fpmacs,cortex_a7_neon_mla"
+ "arm_mac_accumulator_is_result")
+
+;; Non-multiply instructions can issue between two cycles of a
+;; double-precision multiply.
+
+(define_insn_reservation "cortex_a7_fpmuld" 7
+ (and (eq_attr "tune" "cortexa7")
+ (eq_attr "type" "fmuld"))
+ "cortex_a7_ex1+cortex_a7_fpmul_pipe, cortex_a7_fpmul_pipe*3")
+
+(define_insn_reservation "cortex_a7_fpmacd" 11
+ (and (eq_attr "tune" "cortexa7")
+ (eq_attr "type" "fmacd"))
+ "cortex_a7_ex1+cortex_a7_fpmul_pipe, cortex_a7_fpmul_pipe*3")
+
+(define_insn_reservation "cortex_a7_fpfmad" 8
+ (and (eq_attr "tune" "cortexa7")
+ (eq_attr "type" "ffmad"))
+ "cortex_a7_ex1+cortex_a7_fpmul_pipe, cortex_a7_fpmul_pipe*4")
+
+(define_bypass 7 "cortex_a7_fpmacd"
+ "cortex_a7_fpmacd,cortex_a7_fpfmad"
+ "arm_mac_accumulator_is_result")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Floating-point divide/square root instructions.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(define_insn_reservation "cortex_a7_fdivs" 16
+ (and (eq_attr "tune" "cortexa7")
+ (eq_attr "type" "fdivs, fsqrts"))
+ "cortex_a7_ex1+cortex_a7_fp_div_sqrt, cortex_a7_fp_div_sqrt * 13")
+
+(define_insn_reservation "cortex_a7_fdivd" 31
+ (and (eq_attr "tune" "cortexa7")
+ (eq_attr "type" "fdivd, fsqrtd"))
+ "cortex_a7_ex1+cortex_a7_fp_div_sqrt, cortex_a7_fp_div_sqrt * 28")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; VFP to/from core transfers.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Core-to-VFP transfers.
+
+(define_insn_reservation "cortex_a7_r2f" 4
+ (and (eq_attr "tune" "cortexa7")
+ (eq_attr "type" "f_mcr,f_mcrr"))
+ "cortex_a7_both")
+
+(define_insn_reservation "cortex_a7_f2r" 2
+ (and (eq_attr "tune" "cortexa7")
+ (eq_attr "type" "f_mrc,f_mrrc"))
+ "cortex_a7_ex1")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; VFP flag transfer.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Fuxne: The flag forwarding from fmstat to the second instruction is
+;; not modeled at present.
+
+(define_insn_reservation "cortex_a7_f_flags" 4
+ (and (eq_attr "tune" "cortexa7")
+ (eq_attr "type" "f_flag"))
+ "cortex_a7_ex1")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; VFP load/store.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(define_insn_reservation "cortex_a7_f_loads" 4
+ (and (eq_attr "tune" "cortexa7")
+ (eq_attr "type" "f_loads"))
+ "cortex_a7_ex1")
+
+(define_insn_reservation "cortex_a7_f_loadd" 4
+ (and (eq_attr "tune" "cortexa7")
+ (eq_attr "type" "f_loadd"))
+ "cortex_a7_both")
+
+(define_insn_reservation "cortex_a7_f_stores" 0
+ (and (eq_attr "tune" "cortexa7")
+ (eq_attr "type" "f_stores"))
+ "cortex_a7_ex1")
+
+(define_insn_reservation "cortex_a7_f_stored" 0
+ (and (eq_attr "tune" "cortexa7")
+ (eq_attr "type" "f_stored"))
+ "cortex_a7_both")
+
+;; Load-to-use for floating-point values has a penalty of one cycle,
+;; i.e. a latency of two.
+
+(define_bypass 2 "cortex_a7_f_loads, cortex_a7_f_loadd"
+ "cortex_a7_fpalu,\
+ cortex_a7_fpmuls,cortex_a7_fpmacs,\
+ cortex_a7_fpmuld,cortex_a7_fpmacd, cortex_a7_fpfmad,\
+ cortex_a7_fdivs, cortex_a7_fdivd,\
+ cortex_a7_f2r")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; NEON
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; Simple modeling for all neon instructions not covered earlier.
+
+(define_insn_reservation "cortex_a7_neon" 4
+ (and (eq_attr "tune" "cortexa7")
+ (and (eq_attr "is_neon_type" "yes")
+ (eq_attr "cortex_a7_neon_type" "neon_other")))
+ "cortex_a7_both*2")