summaryrefslogtreecommitdiff
path: root/gcc/config/arm
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/arm')
-rw-r--r--gcc/config/arm/iterators.md13
-rw-r--r--gcc/config/arm/vfp.md48
2 files changed, 59 insertions, 2 deletions
diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md
index 795a5ee1634..def8d9f9692 100644
--- a/gcc/config/arm/iterators.md
+++ b/gcc/config/arm/iterators.md
@@ -42,6 +42,9 @@
;; A list of the 32bit and 64bit integer modes
(define_mode_iterator SIDI [SI DI])
+;; A list of modes which the VFP unit can handle
+(define_mode_iterator SDF [(SF "TARGET_VFP") (DF "TARGET_VFP_DOUBLE")])
+
;; Integer element sizes implemented by IWMMXT.
(define_mode_iterator VMMX [V2SI V4HI V8QI])
@@ -245,7 +248,8 @@
(V4HI "P") (V8HI "q")
(V2SI "P") (V4SI "q")
(V2SF "P") (V4SF "q")
- (DI "P") (V2DI "q")])
+ (DI "P") (V2DI "q")
+ (SF "") (DF "P")])
;; Wider modes with the same number of elements.
(define_mode_attr V_widen [(V8QI "V8HI") (V4HI "V4SI") (V2SI "V2DI")])
@@ -303,7 +307,8 @@
(V4HI "i16") (V8HI "i16")
(V2SI "i32") (V4SI "i32")
(DI "i64") (V2DI "i64")
- (V2SF "f32") (V4SF "f32")])
+ (V2SF "f32") (V4SF "f32")
+ (SF "f32") (DF "f64")])
;; Same, but for operations which work on signed values.
(define_mode_attr V_s_elem [(V8QI "s8") (V16QI "s8")
@@ -423,6 +428,10 @@
;; Mode attribute for vshll.
(define_mode_attr V_innermode [(V8QI "QI") (V4HI "HI") (V2SI "SI")])
+;; Mode attributes used for fused-multiply-accumulate VFP support
+(define_mode_attr F_constraint [(SF "t") (DF "w")])
+(define_mode_attr F_fma_type [(SF "fmacs") (DF "fmacd")])
+
;;----------------------------------------------------------------------------
;; Code attributes
;;----------------------------------------------------------------------------
diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md
index 20614144d29..3d18ecbc337 100644
--- a/gcc/config/arm/vfp.md
+++ b/gcc/config/arm/vfp.md
@@ -890,6 +890,54 @@
(set_attr "type" "fmacd")]
)
+;; Fused-multiply-accumulate
+
+(define_insn "fma<SDF:mode>4"
+ [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>")
+ (fma:SDF (match_operand:SDF 1 "register_operand" "<F_constraint>")
+ (match_operand:SDF 2 "register_operand" "<F_constraint>")
+ (match_operand:SDF 3 "register_operand" "0")))]
+ "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" "<F_fma_type>")]
+)
+
+(define_insn "*fmsub<SDF:mode>4"
+ [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>")
+ (fma:SDF (neg:SDF (match_operand:SDF 1 "register_operand"
+ "<F_constraint>"))
+ (match_operand:SDF 2 "register_operand" "<F_constraint>")
+ (match_operand:SDF 3 "register_operand" "0")))]
+ "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" "<F_fma_type>")]
+)
+
+(define_insn "*fnmsub<SDF:mode>4"
+ [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>")
+ (fma:SDF (match_operand:SDF 1 "register_operand" "<F_constraint>")
+ (match_operand:SDF 2 "register_operand" "<F_constraint>")
+ (neg:SDF (match_operand:SDF 3 "register_operand" "0"))))]
+ "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" "<F_fma_type>")]
+)
+
+(define_insn "*fnmadd<SDF:mode>4"
+ [(set (match_operand:SDF 0 "register_operand" "=<F_constraint>")
+ (fma:SDF (neg:SDF (match_operand:SDF 1 "register_operand"
+ "<F_constraint>"))
+ (match_operand:SDF 2 "register_operand" "<F_constraint>")
+ (neg:SDF (match_operand:SDF 3 "register_operand" "0"))))]
+ "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" "<F_fma_type>")]
+)
+
;; Conversion routines