Fused and not fused multiply and accumulated operations may have different
timing characteristics, for example in Cortex-A7. Currently, the compiler
captures all of these operations using the same "type" attribute fmac.

This patch adds a new "type" attribute ffma to separate fused operations
from other fmac operations, for both single and double precision floating
point. The patch also updates existing pipeline descriptions to use both
fmac and ffma whenever fmac was used, so that the generated code remains
unaffected.

A subsequent patch for Cortex-A7 pipeline description takes advantage of the
distinction between fused and other mac operations.

gcc/

2013-01-03  Greta Yorsh  <greta.yo...@arm.com>

        * config/arm/arm.md (type): Add ffmas and ffmad to "type" attribute.
        * config/arm/vfp.md (fma,fmsub,fnmsub,fnmadd): Change type
        from fmac to ffma.
        * config/arm/vfp11.md (vfp_farith): Use ffmas.
        (vfp_fmul): Use ffmad.
        * config/arm/cortex-r4f.md (cortex_r4_fmacs): Use ffmas.
        (cortex_r4_fmacd): Use ffmad.
        * config/arm/cortex-m4-fpu.md (cortex_m4_fmacs): Use ffmas.
        * config/arm/cortex-a9.md (cortex_a9_fmacs):  Use ffmas.
        (cortex_a9_fmacd): Use ffmad.
        * config/arm/cortex-a8-neon.md (cortex_a8_vfp_macs): Use ffmas.
        (cortex_a8_vfp_macd): Use ffmad.
        * config/arm/cortex-a5.md (cortex_a5_fpmacs): Use ffmas.
        (cortex_a5_fpmacd): Use ffmad.
        * config/arm/cortex-a15-neon.md (cortex_a15_vfp_macs) Use ffmas.
        (cortex_a15_vfp_macd): Use ffmad.
        * config/arm/arm1020e.md (v10_fmul): Use ffmas and ffmad.
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 
6b8e9a75fa4ca7f4f09ae34f5b69c1b71044f9d8..0000000000000000000000000000000000000000
 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -284,6 +284,8 @@ (define_attr "type"
   fmuld,\
   fmacs,\
   fmacd,\
+  ffmas,\
+  ffmad,\
   f_rints,\
   f_rintd,\
   f_flag,\
diff --git a/gcc/config/arm/arm1020e.md b/gcc/config/arm/arm1020e.md
index 
9a41d30573605d845385e79966737f44ee61e168..0000000000000000000000000000000000000000
 100644
--- a/gcc/config/arm/arm1020e.md
+++ b/gcc/config/arm/arm1020e.md
@@ -284,7 +284,7 @@ (define_insn_reservation "v10_cvt" 5
 
 (define_insn_reservation "v10_fmul" 6
  (and (eq_attr "vfp10" "yes")
-      (eq_attr "type" "fmuls,fmacs,fmuld,fmacd"))
+      (eq_attr "type" "fmuls,fmacs,ffmas,fmuld,fmacd,ffmad"))
  "1020a_e+v10_fmac*2")
 
 (define_insn_reservation "v10_fdivs" 18
diff --git a/gcc/config/arm/cortex-a15-neon.md 
b/gcc/config/arm/cortex-a15-neon.md
index 
afb67a587526fae8145a8474871cc1d4fbe7e3c9..0000000000000000000000000000000000000000
 100644
--- a/gcc/config/arm/cortex-a15-neon.md
+++ b/gcc/config/arm/cortex-a15-neon.md
@@ -505,12 +505,12 @@ (define_insn_reservation "cortex_a15_vfp
 
 (define_insn_reservation "cortex_a15_vfp_macs" 6
   (and (eq_attr "tune" "cortexa15")
-       (eq_attr "type" "fmacs"))
+       (eq_attr "type" "fmacs,ffmas"))
   "ca15_issue1,ca15_cx_vfp")
 
 (define_insn_reservation "cortex_a15_vfp_macd" 11
   (and (eq_attr "tune" "cortexa15")
-       (eq_attr "type" "fmacd"))
+       (eq_attr "type" "fmacd,ffmad"))
   "ca15_issue2,ca15_cx_vfp*2")
 
 (define_insn_reservation "cortex_a15_vfp_cvt" 6
diff --git a/gcc/config/arm/cortex-a5.md b/gcc/config/arm/cortex-a5.md
index 
2b5abe524a63a6c90fc3da1b255b163d44c1455b..0000000000000000000000000000000000000000
 100644
--- a/gcc/config/arm/cortex-a5.md
+++ b/gcc/config/arm/cortex-a5.md
@@ -185,7 +185,7 @@ (define_insn_reservation "cortex_a5_fpmu
 
 (define_insn_reservation "cortex_a5_fpmacs" 8
   (and (eq_attr "tune" "cortexa5")
-       (eq_attr "type" "fmacs"))
+       (eq_attr "type" "fmacs,ffmas"))
   "cortex_a5_ex1+cortex_a5_fpmul_pipe, nothing*3, cortex_a5_fpadd_pipe")
 
 ;; Non-multiply instructions can issue in the middle two instructions of a
@@ -201,7 +201,7 @@ (define_insn_reservation "cortex_a5_fpmu
 
 (define_insn_reservation "cortex_a5_fpmacd" 11
   (and (eq_attr "tune" "cortexa5")
-       (eq_attr "type" "fmacd"))
+       (eq_attr "type" "fmacd,ffmad"))
   "cortex_a5_ex1+cortex_a5_fpmul_pipe, cortex_a5_fpmul_pipe*2,\
    cortex_a5_ex1+cortex_a5_fpmul_pipe, nothing*3, cortex_a5_fpadd_pipe")
 
diff --git a/gcc/config/arm/cortex-a8-neon.md b/gcc/config/arm/cortex-a8-neon.md
index 
03f52b2df8a99ea709ac42cabcc32de587ac403f..0000000000000000000000000000000000000000
 100644
--- a/gcc/config/arm/cortex-a8-neon.md
+++ b/gcc/config/arm/cortex-a8-neon.md
@@ -149,12 +149,12 @@ (define_insn_reservation "cortex_a8_vfp_
 
 (define_insn_reservation "cortex_a8_vfp_macs" 21
   (and (eq_attr "tune" "cortexa8")
-       (eq_attr "type" "fmacs"))
+       (eq_attr "type" "fmacs,ffmas"))
   "cortex_a8_vfp,cortex_a8_vfplite*20")
 
 (define_insn_reservation "cortex_a8_vfp_macd" 26
   (and (eq_attr "tune" "cortexa8")
-       (eq_attr "type" "fmacd"))
+       (eq_attr "type" "fmacd,ffmad"))
   "cortex_a8_vfp,cortex_a8_vfplite*25")
 
 (define_insn_reservation "cortex_a8_vfp_divs" 37
diff --git a/gcc/config/arm/cortex-a9.md b/gcc/config/arm/cortex-a9.md
index 
f1bd7cfa91a5875069fcdf14da230112eb28d32e..0000000000000000000000000000000000000000
 100644
--- a/gcc/config/arm/cortex-a9.md
+++ b/gcc/config/arm/cortex-a9.md
@@ -203,7 +203,7 @@ (define_insn_reservation "cortex_a9_call
 ;; Pipeline   Instruction Classification.
 ;; FPS - fcpys, ffariths, ffarithd,r_2_f,f_2_r
 ;; FP_ADD   - fadds, faddd, fcmps (1)
-;; FPMUL   - fmul{s,d}, fmac{s,d}
+;; FPMUL   - fmul{s,d}, fmac{s,d}, ffma{s,d}
 ;; FPDIV - fdiv{s,d}
 (define_cpu_unit "ca9fps" "cortex_a9")
 (define_cpu_unit "ca9fp_add1, ca9fp_add2, ca9fp_add3, ca9fp_add4" "cortex_a9")
@@ -253,12 +253,12 @@ (define_insn_reservation "cortex_a9_fmul
 
 (define_insn_reservation "cortex_a9_fmacs" 8
   (and (eq_attr "tune" "cortexa9")
-       (eq_attr "type" "fmacs"))
+       (eq_attr "type" "fmacs,ffmas"))
   "ca9fmuls, ca9fp_add")
 
 (define_insn_reservation "cortex_a9_fmacd" 9
   (and (eq_attr "tune" "cortexa9")
-       (eq_attr "type" "fmacd"))
+       (eq_attr "type" "fmacd,ffmad"))
   "ca9fmuld, ca9fp_add")
 
 ;; Division pipeline description.
diff --git a/gcc/config/arm/cortex-m4-fpu.md b/gcc/config/arm/cortex-m4-fpu.md
index 
6fd5faf74ee6336c7cc865946bf2db5d2bcc14cb..0000000000000000000000000000000000000000
 100644
--- a/gcc/config/arm/cortex-m4-fpu.md
+++ b/gcc/config/arm/cortex-m4-fpu.md
@@ -46,7 +46,7 @@ (define_insn_reservation "cortex_m4_fmul
 
 (define_insn_reservation "cortex_m4_fmacs" 4
   (and (eq_attr "tune" "cortexm4")
-       (eq_attr "type" "fmacs"))
+       (eq_attr "type" "fmacs,ffmas"))
   "cortex_m4_ex_v*3")
 
 (define_insn_reservation "cortex_m4_ffariths" 1
diff --git a/gcc/config/arm/cortex-r4f.md b/gcc/config/arm/cortex-r4f.md
index 
8982bc068eb3f5276d50a4871bfa28b73bd1f31a..0000000000000000000000000000000000000000
 100644
--- a/gcc/config/arm/cortex-r4f.md
+++ b/gcc/config/arm/cortex-r4f.md
@@ -63,7 +63,7 @@ (define_insn_reservation "cortex_r4_fari
 
 (define_insn_reservation "cortex_r4_fmacs" 6
  (and (eq_attr "tune_cortexr4" "yes")
-      (eq_attr "type" "fmacs"))
+      (eq_attr "type" "fmacs,ffmas"))
  "(cortex_r4_issue_a+cortex_r4_v1)|(cortex_r4_issue_b+cortex_r4_vmla)")
 
 (define_insn_reservation "cortex_r4_fdivs" 17
@@ -119,7 +119,7 @@ (define_bypass 16 "cortex_r4_fdivs"
 
 (define_insn_reservation "cortex_r4_fmacd" 20
  (and (eq_attr "tune_cortexr4" "yes")
-      (eq_attr "type" "fmacd"))
+      (eq_attr "type" "fmacd,ffmad"))
  "cortex_r4_single_issue*13")
 
 (define_insn_reservation "cortex_r4_farith" 10
diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md
index 
a5c461df36f9dd6613a03d5d68d58dab851252ba..0000000000000000000000000000000000000000
 100644
--- a/gcc/config/arm/vfp.md
+++ b/gcc/config/arm/vfp.md
@@ -33,6 +33,8 @@
 ;; fmuld       Double precision multiply.
 ;; fmacs       Single precision multiply-accumulate.
 ;; fmacd       Double precision multiply-accumulate.
+;; ffmas       Single precision fused multiply-accumulate.
+;; ffmad       Double precision fused multiply-accumulate.
 ;; fdivs       Single precision sqrt or division.
 ;; fdivd       Double precision sqrt or division.
 ;; f_flag      fmstat operation
@@ -910,7 +912,7 @@ (define_insn "fma<SDF:mode>4"
   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA"
   "vfma%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
   [(set_attr "predicable" "yes")
-   (set_attr "type" "fmac<vfp_type>")]
+   (set_attr "type" "ffma<vfp_type>")]
 )
 
 (define_insn "*fmsub<SDF:mode>4"
@@ -922,7 +924,7 @@ (define_insn "*fmsub<SDF:mode>4"
   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA"
   "vfms%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
   [(set_attr "predicable" "yes")
-   (set_attr "type" "fmac<vfp_type>")]
+   (set_attr "type" "ffma<vfp_type>")]
 )
 
 (define_insn "*fnmsub<SDF:mode>4"
@@ -933,7 +935,7 @@ (define_insn "*fnmsub<SDF:mode>4"
   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA"
   "vfnms%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
   [(set_attr "predicable" "yes")
-   (set_attr "type" "fmac<vfp_type>")]
+   (set_attr "type" "ffma<vfp_type>")]
 )
 
 (define_insn "*fnmadd<SDF:mode>4"
@@ -945,7 +947,7 @@ (define_insn "*fnmadd<SDF:mode>4"
   "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FMA"
   "vfnma%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
   [(set_attr "predicable" "yes")
-   (set_attr "type" "fmac<vfp_type>")]
+   (set_attr "type" "ffma<vfp_type>")]
 )
 
 
diff --git a/gcc/config/arm/vfp11.md b/gcc/config/arm/vfp11.md
index 
8f863fd70cd0a5124675bac8211249fb3db7170e..0000000000000000000000000000000000000000
 100644
--- a/gcc/config/arm/vfp11.md
+++ b/gcc/config/arm/vfp11.md
@@ -56,12 +56,12 @@ (define_insn_reservation "vfp_ffarith" 4
 
 (define_insn_reservation "vfp_farith" 8
  (and (eq_attr "generic_vfp" "yes")
-      (eq_attr "type" "fadds,faddd,fconsts,fconstd,f_cvt,fmuls,fmacs"))
+      (eq_attr "type" "fadds,faddd,fconsts,fconstd,f_cvt,fmuls,fmacs,ffmas"))
  "fmac")
 
 (define_insn_reservation "vfp_fmul" 9
  (and (eq_attr "generic_vfp" "yes")
-      (eq_attr "type" "fmuld,fmacd"))
+      (eq_attr "type" "fmuld,fmacd,ffmad"))
  "fmac*2")
 
 (define_insn_reservation "vfp_fdivs" 19

Reply via email to