Commit 3e5804e1 by Uros Bizjak Committed by Uros Bizjak

i386.md (isa): Add fma and fma4.

	* config/i386/i386.md (isa): Add fma and fma4.
	(enabled): Handle fma and fma4.
	* config/i386/sse.md (*fma_fmadd_<mode>): Merge *fma4_fmadd_<mode>.
	(*fma_fmsub_<mode>): Merge *fma4_fmsub_<mode>.
	(*fma_fnmadd_<mode>): Merge *fma4_fnmadd_<mode>.
	(*fma_fnmsub_<mode>): Merge *fma4_fnmsub_<mode>.
	(*fma_fmaddsub_<mode>): Merge *fma4_fmaddsub_<mode>.
	(*fma_fmsubadd_<mode>): Merge *fma4_fmsubadd_<mode>.

From-SVN: r190305
parent b0d5396c
2012-08-11 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.md (isa): Add fma and fma4.
(enabled): Handle fma and fma4.
* config/i386/sse.md (*fma_fmadd_<mode>): Merge *fma4_fmadd_<mode>.
(*fma_fmsub_<mode>): Merge *fma4_fmsub_<mode>.
(*fma_fnmadd_<mode>): Merge *fma4_fnmadd_<mode>.
(*fma_fnmsub_<mode>): Merge *fma4_fnmsub_<mode>.
(*fma_fmaddsub_<mode>): Merge *fma4_fmaddsub_<mode>.
(*fma_fmsubadd_<mode>): Merge *fma4_fmsubadd_<mode>.
2012-08-10 Uros Bizjak <ubizjak@gmail.com> 2012-08-10 Uros Bizjak <ubizjak@gmail.com>
* config/i386/sse.md (*fma_fmadd_<mode>, *fma_fmsub_<mode>, * config/i386/sse.md (*fma_fmadd_<mode>, *fma_fmsub_<mode>,
......
...@@ -641,7 +641,8 @@ ...@@ -641,7 +641,8 @@
(define_attr "movu" "0,1" (const_string "0")) (define_attr "movu" "0,1" (const_string "0"))
;; Used to control the "enabled" attribute on a per-instruction basis. ;; Used to control the "enabled" attribute on a per-instruction basis.
(define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,avx2,noavx2,bmi2" (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,
avx2,noavx2,bmi2,fma,fma4"
(const_string "base")) (const_string "base"))
(define_attr "enabled" "" (define_attr "enabled" ""
...@@ -657,6 +658,9 @@ ...@@ -657,6 +658,9 @@
(eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2") (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
(eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2") (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
(eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2") (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
(eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
(eq_attr "isa" "fma4")
(symbol_ref "TARGET_FMA4 && !TARGET_FMA")
] ]
(const_int 1))) (const_int 1)))
......
...@@ -1891,21 +1891,6 @@ ...@@ -1891,21 +1891,6 @@
(define_mode_iterator FMAMODE [SF DF V4SF V2DF V8SF V4DF]) (define_mode_iterator FMAMODE [SF DF V4SF V2DF V8SF V4DF])
;; In order to match (*a * *b) + *c, particularly when vectorizing, allow
;; combine to generate a multiply/add with two memory references. We then
;; split this insn, into loading up the destination register with one of the
;; memory operations. If we don't manage to split the insn, reload will
;; generate the appropriate moves. The reason this is needed, is that combine
;; has already folded one of the memory references into both the multiply and
;; add insns, and it can't generate a new pseudo. I.e.:
;; (set (reg1) (mem (addr1)))
;; (set (reg2) (mult (reg1) (mem (addr2))))
;; (set (reg3) (plus (reg2) (mem (addr3))))
;;
;; ??? This is historic, pre-dating the gimple fma transformation.
;; We could now properly represent that only one memory operand is
;; allowed and not be penalized during optimization.
;; The standard names for fma is only available with SSE math enabled. ;; The standard names for fma is only available with SSE math enabled.
(define_expand "fma<mode>4" (define_expand "fma<mode>4"
[(set (match_operand:FMAMODE 0 "register_operand") [(set (match_operand:FMAMODE 0 "register_operand")
...@@ -1948,116 +1933,76 @@ ...@@ -1948,116 +1933,76 @@
(match_operand:FMAMODE 3 "nonimmediate_operand")))] (match_operand:FMAMODE 3 "nonimmediate_operand")))]
"TARGET_FMA || TARGET_FMA4") "TARGET_FMA || TARGET_FMA4")
;; FMA3 version
(define_insn "*fma_fmadd_<mode>" (define_insn "*fma_fmadd_<mode>"
[(set (match_operand:FMAMODE 0 "register_operand" "=x,x,x") [(set (match_operand:FMAMODE 0 "register_operand" "=x,x,x,x,x")
(fma:FMAMODE (fma:FMAMODE
(match_operand:FMAMODE 1 "nonimmediate_operand" "%0, 0,x") (match_operand:FMAMODE 1 "nonimmediate_operand" "%0, 0,x, x,x")
(match_operand:FMAMODE 2 "nonimmediate_operand" "xm, x,xm") (match_operand:FMAMODE 2 "nonimmediate_operand" "xm, x,xm,x,m")
(match_operand:FMAMODE 3 "nonimmediate_operand" " x,xm,0")))] (match_operand:FMAMODE 3 "nonimmediate_operand" " x,xm,0,xm,x")))]
"TARGET_FMA" "TARGET_FMA || TARGET_FMA4"
"@ "@
vfmadd132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2} vfmadd132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2}
vfmadd213<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3} vfmadd213<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}
vfmadd231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" vfmadd231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}
[(set_attr "type" "ssemuladd") vfmadd<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}
vfmadd<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "isa" "fma,fma,fma,fma4,fma4")
(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")]) (set_attr "mode" "<MODE>")])
(define_insn "*fma_fmsub_<mode>" (define_insn "*fma_fmsub_<mode>"
[(set (match_operand:FMAMODE 0 "register_operand" "=x,x,x") [(set (match_operand:FMAMODE 0 "register_operand" "=x,x,x,x,x")
(fma:FMAMODE (fma:FMAMODE
(match_operand:FMAMODE 1 "nonimmediate_operand" "%0, 0,x") (match_operand:FMAMODE 1 "nonimmediate_operand" "%0, 0,x, x,x")
(match_operand:FMAMODE 2 "nonimmediate_operand" "xm, x,xm") (match_operand:FMAMODE 2 "nonimmediate_operand" "xm, x,xm,x,m")
(neg:FMAMODE (neg:FMAMODE
(match_operand:FMAMODE 3 "nonimmediate_operand" " x,xm,0"))))] (match_operand:FMAMODE 3 "nonimmediate_operand" " x,xm,0,xm,x"))))]
"TARGET_FMA" "TARGET_FMA || TARGET_FMA4"
"@ "@
vfmsub132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2} vfmsub132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2}
vfmsub213<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3} vfmsub213<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}
vfmsub231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" vfmsub231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}
[(set_attr "type" "ssemuladd") vfmsub<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}
vfmsub<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "isa" "fma,fma,fma,fma4,fma4")
(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")]) (set_attr "mode" "<MODE>")])
(define_insn "*fma_fnmadd_<mode>" (define_insn "*fma_fnmadd_<mode>"
[(set (match_operand:FMAMODE 0 "register_operand" "=x,x,x") [(set (match_operand:FMAMODE 0 "register_operand" "=x,x,x,x,x")
(fma:FMAMODE (fma:FMAMODE
(neg:FMAMODE (neg:FMAMODE
(match_operand:FMAMODE 1 "nonimmediate_operand" "%0, 0,x")) (match_operand:FMAMODE 1 "nonimmediate_operand" "%0, 0,x, x,x"))
(match_operand:FMAMODE 2 "nonimmediate_operand" "xm, x,xm") (match_operand:FMAMODE 2 "nonimmediate_operand" "xm, x,xm,x,m")
(match_operand:FMAMODE 3 "nonimmediate_operand" " x,xm,0")))] (match_operand:FMAMODE 3 "nonimmediate_operand" " x,xm,0,xm,x")))]
"TARGET_FMA" "TARGET_FMA || TARGET_FMA4"
"@ "@
vfnmadd132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2} vfnmadd132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2}
vfnmadd213<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3} vfnmadd213<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}
vfnmadd231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" vfnmadd231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}
[(set_attr "type" "ssemuladd") vfnmadd<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}
vfnmadd<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "isa" "fma,fma,fma,fma4,fma4")
(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")]) (set_attr "mode" "<MODE>")])
(define_insn "*fma_fnmsub_<mode>" (define_insn "*fma_fnmsub_<mode>"
[(set (match_operand:FMAMODE 0 "register_operand" "=x,x,x") [(set (match_operand:FMAMODE 0 "register_operand" "=x,x,x,x,x")
(fma:FMAMODE (fma:FMAMODE
(neg:FMAMODE (neg:FMAMODE
(match_operand:FMAMODE 1 "nonimmediate_operand" "%0, 0,x")) (match_operand:FMAMODE 1 "nonimmediate_operand" "%0, 0,x, x,x"))
(match_operand:FMAMODE 2 "nonimmediate_operand" "xm, x,xm") (match_operand:FMAMODE 2 "nonimmediate_operand" "xm, x,xm,x,m")
(neg:FMAMODE (neg:FMAMODE
(match_operand:FMAMODE 3 "nonimmediate_operand" " x,xm,0"))))] (match_operand:FMAMODE 3 "nonimmediate_operand" " x,xm,0,xm,x"))))]
"TARGET_FMA" "TARGET_FMA || TARGET_FMA4"
"@ "@
vfnmsub132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2} vfnmsub132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2}
vfnmsub213<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3} vfnmsub213<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}
vfnmsub231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" vfnmsub231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}
[(set_attr "type" "ssemuladd") vfnmsub<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}
(set_attr "mode" "<MODE>")]) vfnmsub<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "isa" "fma,fma,fma,fma4,fma4")
;; FMA4 version (set_attr "type" "ssemuladd")
(define_insn "*fma4_fmadd_<mode>"
[(set (match_operand:FMAMODE 0 "register_operand" "=x,x")
(fma:FMAMODE
(match_operand:FMAMODE 1 "nonimmediate_operand" "%x,x")
(match_operand:FMAMODE 2 "nonimmediate_operand" " x,m")
(match_operand:FMAMODE 3 "nonimmediate_operand" "xm,x")))]
"TARGET_FMA4"
"vfmadd<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")])
(define_insn "*fma4_fmsub_<mode>"
[(set (match_operand:FMAMODE 0 "register_operand" "=x,x")
(fma:FMAMODE
(match_operand:FMAMODE 1 "nonimmediate_operand" "%x,x")
(match_operand:FMAMODE 2 "nonimmediate_operand" " x,m")
(neg:FMAMODE
(match_operand:FMAMODE 3 "nonimmediate_operand" "xm,x"))))]
"TARGET_FMA4"
"vfmsub<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")])
(define_insn "*fma4_fnmadd_<mode>"
[(set (match_operand:FMAMODE 0 "register_operand" "=x,x")
(fma:FMAMODE
(neg:FMAMODE
(match_operand:FMAMODE 1 "nonimmediate_operand" "%x,x"))
(match_operand:FMAMODE 2 "nonimmediate_operand" " x,m")
(match_operand:FMAMODE 3 "nonimmediate_operand" "xm,x")))]
"TARGET_FMA4"
"vfnmadd<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")])
(define_insn "*fma4_fnmsub_<mode>"
[(set (match_operand:FMAMODE 0 "register_operand" "=x,x")
(fma:FMAMODE
(neg:FMAMODE
(match_operand:FMAMODE 1 "nonimmediate_operand" "%x,x"))
(match_operand:FMAMODE 2 "nonimmediate_operand" " x,m")
(neg:FMAMODE
(match_operand:FMAMODE 3 "nonimmediate_operand" "xm,x"))))]
"TARGET_FMA4"
"vfnmsub<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")]) (set_attr "mode" "<MODE>")])
;; FMA parallel floating point multiply addsub and subadd operations. ;; FMA parallel floating point multiply addsub and subadd operations.
...@@ -2080,64 +2025,41 @@ ...@@ -2080,64 +2025,41 @@
UNSPEC_FMADDSUB))] UNSPEC_FMADDSUB))]
"TARGET_FMA || TARGET_FMA4") "TARGET_FMA || TARGET_FMA4")
;; FMA3 version
(define_insn "*fma_fmaddsub_<mode>" (define_insn "*fma_fmaddsub_<mode>"
[(set (match_operand:VF 0 "register_operand" "=x,x,x") [(set (match_operand:VF 0 "register_operand" "=x,x,x,x,x")
(unspec:VF (unspec:VF
[(match_operand:VF 1 "nonimmediate_operand" "%0, 0,x") [(match_operand:VF 1 "nonimmediate_operand" "%0, 0,x, x,x")
(match_operand:VF 2 "nonimmediate_operand" "xm, x,xm") (match_operand:VF 2 "nonimmediate_operand" "xm, x,xm,x,m")
(match_operand:VF 3 "nonimmediate_operand" " x,xm,0")] (match_operand:VF 3 "nonimmediate_operand" " x,xm,0,xm,x")]
UNSPEC_FMADDSUB))] UNSPEC_FMADDSUB))]
"TARGET_FMA" "TARGET_FMA || TARGET_FMA4"
"@ "@
vfmaddsub132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2} vfmaddsub132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2}
vfmaddsub213<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3} vfmaddsub213<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}
vfmaddsub231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" vfmaddsub231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}
[(set_attr "type" "ssemuladd") vfmaddsub<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}
vfmaddsub<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "isa" "fma,fma,fma,fma4,fma4")
(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")]) (set_attr "mode" "<MODE>")])
(define_insn "*fma_fmsubadd_<mode>" (define_insn "*fma_fmsubadd_<mode>"
[(set (match_operand:VF 0 "register_operand" "=x,x,x") [(set (match_operand:VF 0 "register_operand" "=x,x,x,x,x")
(unspec:VF (unspec:VF
[(match_operand:VF 1 "nonimmediate_operand" "%0, 0,x") [(match_operand:VF 1 "nonimmediate_operand" "%0, 0,x, x,x")
(match_operand:VF 2 "nonimmediate_operand" "xm, x,xm") (match_operand:VF 2 "nonimmediate_operand" "xm, x,xm,x,m")
(neg:VF (neg:VF
(match_operand:VF 3 "nonimmediate_operand" " x,xm,0"))] (match_operand:VF 3 "nonimmediate_operand" " x,xm,0,xm,x"))]
UNSPEC_FMADDSUB))] UNSPEC_FMADDSUB))]
"TARGET_FMA" "TARGET_FMA || TARGET_FMA4"
"@ "@
vfmsubadd132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2} vfmsubadd132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2}
vfmsubadd213<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3} vfmsubadd213<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}
vfmsubadd231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}" vfmsubadd231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}
[(set_attr "type" "ssemuladd") vfmsubadd<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}
(set_attr "mode" "<MODE>")]) vfmsubadd<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "isa" "fma,fma,fma,fma4,fma4")
;; FMA4 version (set_attr "type" "ssemuladd")
(define_insn "*fma4_fmaddsub_<mode>"
[(set (match_operand:VF 0 "register_operand" "=x,x")
(unspec:VF
[(match_operand:VF 1 "nonimmediate_operand" "%x,x")
(match_operand:VF 2 "nonimmediate_operand" " x,m")
(match_operand:VF 3 "nonimmediate_operand" "xm,x")]
UNSPEC_FMADDSUB))]
"TARGET_FMA4"
"vfmaddsub<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")])
(define_insn "*fma4_fmsubadd_<mode>"
[(set (match_operand:VF 0 "register_operand" "=x,x")
(unspec:VF
[(match_operand:VF 1 "nonimmediate_operand" "%x,x")
(match_operand:VF 2 "nonimmediate_operand" " x,m")
(neg:VF
(match_operand:VF 3 "nonimmediate_operand" "xm,x"))]
UNSPEC_FMADDSUB))]
"TARGET_FMA4"
"vfmsubadd<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
[(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")]) (set_attr "mode" "<MODE>")])
;; FMA3 floating point scalar intrinsics. These merge result with ;; FMA3 floating point scalar intrinsics. These merge result with
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment