aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeffrey A Law <law@cygnus.com>1999-09-22 20:24:45 +0000
committerJeff Law <law@gcc.gnu.org>1999-09-22 14:24:45 -0600
commit9a40d6bc0c227843acdae95248f17fc8c7bf81e6 (patch)
tree9204c161300bf602acd79499ef6fd7b84e98205f
parent80559c31a6955c02751911a9af2a8446432f2eae (diff)
downloadgcc-9a40d6bc0c227843acdae95248f17fc8c7bf81e6.zip
gcc-9a40d6bc0c227843acdae95248f17fc8c7bf81e6.tar.gz
gcc-9a40d6bc0c227843acdae95248f17fc8c7bf81e6.tar.bz2
pa.md (fused multiply): Add variants which reduce height for the fused multiply...
* pa.md (fused multiply): Add variants which reduce height for the fused multiply, but which still generate 2 insns. (fnegabs): Similarly. From-SVN: r29598
-rw-r--r--gcc/ChangeLog4
-rw-r--r--gcc/config/pa/pa.md280
2 files changed, 284 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6cd7f82..982be6d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -37,6 +37,10 @@ Wed Sep 22 06:25:15 1999 Jim Kingdon <http://developer.redhat.com>
Wed Sep 22 06:06:57 1999 Jeffrey A Law (law@cygnus.com)
+ * pa.md (fused multiply): Add variants which reduce height for the
+ fused multiply, but which still generate 2 insns.
+ (fnegabs): Similarly.
+
* pa.md (subsi3): Turn into an expander. Create two anonymous
patterns. One for PA2.0 one for PA1.x. Use mtsarcm for PA2.0.
* pa.h (EXTRA_CONSTRAINT): Handle 'S'.
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index 545d13a..6e98c95 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -3886,6 +3886,286 @@
[(set_attr "type" "fpalu")
(set_attr "length" "4")])
+;; Generating a fused multiply sequence is a win for this case as it will
+;; reduce the latency for the fused case without impacting the plain
+;; multiply case.
+;;
+;; Similar possibilities exist for fnegabs, shadd and other insns which
+;; perform two operations with the result of the first feeding the second.
+(define_insn ""
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
+ (match_operand:DF 2 "register_operand" "f"))
+ (match_operand:DF 3 "register_operand" "f")))
+ (set (match_operand:DF 4 "register_operand" "=&f")
+ (mult:DF (match_dup 1) (match_dup 2)))]
+ "! TARGET_SOFT_FLOAT && TARGET_PA_20"
+ "#"
+ [(set_attr "type" "fpmuldbl")
+ (set_attr "length" "8")])
+
+;; We want to split this up during scheduling since we want both insns
+;; to schedule independently.
+(define_split
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
+ (match_operand:DF 2 "register_operand" "f"))
+ (match_operand:DF 3 "register_operand" "f")))
+ (set (match_operand:DF 4 "register_operand" "=&f")
+ (mult:DF (match_dup 1) (match_dup 2)))]
+ "! TARGET_SOFT_FLOAT && TARGET_PA_20"
+ [(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2)))
+ (set (match_dup 0) (plus:DF (mult:DF (match_dup 1) (match_dup 2))
+ (match_dup 3)))]
+ "")
+
+(define_insn ""
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
+ (match_operand:SF 2 "register_operand" "f"))
+ (match_operand:SF 3 "register_operand" "f")))
+ (set (match_operand:SF 4 "register_operand" "=&f")
+ (mult:SF (match_dup 1) (match_dup 2)))]
+ "! TARGET_SOFT_FLOAT && TARGET_PA_20"
+ "#"
+ [(set_attr "type" "fpmuldbl")
+ (set_attr "length" "8")])
+
+;; We want to split this up during scheduling since we want both insns
+;; to schedule independently.
+(define_split
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
+ (match_operand:SF 2 "register_operand" "f"))
+ (match_operand:SF 3 "register_operand" "f")))
+ (set (match_operand:SF 4 "register_operand" "=&f")
+ (mult:SF (match_dup 1) (match_dup 2)))]
+ "! TARGET_SOFT_FLOAT && TARGET_PA_20"
+ [(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2)))
+ (set (match_dup 0) (plus:SF (mult:SF (match_dup 1) (match_dup 2))
+ (match_dup 3)))]
+ "")
+
+;; Negating a multiply can be faked by adding zero in a fused multiply-add
+;; instruction.
+(define_insn ""
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
+ (match_operand:DF 2 "register_operand" "f"))))]
+ "! TARGET_SOFT_FLOAT && TARGET_PA_20"
+ "fmpynfadd,dbl %1,%2,0,%0"
+ [(set_attr "type" "fpmuldbl")
+ (set_attr "length" "4")])
+
+(define_insn ""
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
+ (match_operand:SF 2 "register_operand" "f"))))]
+ "! TARGET_SOFT_FLOAT && TARGET_PA_20"
+ "fmpynfadd,sgl %1,%2,0,%0"
+ [(set_attr "type" "fpmuldbl")
+ (set_attr "length" "4")])
+
+(define_insn ""
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
+ (match_operand:DF 2 "register_operand" "f"))))
+ (set (match_operand:DF 3 "register_operand" "=&f")
+ (mult:DF (match_dup 1) (match_dup 2)))]
+ "! TARGET_SOFT_FLOAT && TARGET_PA_20"
+ "#"
+ [(set_attr "type" "fpmuldbl")
+ (set_attr "length" "8")])
+
+(define_split
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
+ (match_operand:DF 2 "register_operand" "f"))))
+ (set (match_operand:DF 3 "register_operand" "=&f")
+ (mult:DF (match_dup 1) (match_dup 2)))]
+ "! TARGET_SOFT_FLOAT && TARGET_PA_20"
+ [(set (match_dup 3) (mult:DF (match_dup 1) (match_dup 2)))
+ (set (match_dup 0) (neg:DF (mult:DF (match_dup 1) (match_dup 2))))]
+ "")
+
+(define_insn ""
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
+ (match_operand:SF 2 "register_operand" "f"))))
+ (set (match_operand:SF 3 "register_operand" "=&f")
+ (mult:SF (match_dup 1) (match_dup 2)))]
+ "! TARGET_SOFT_FLOAT && TARGET_PA_20"
+ "#"
+ [(set_attr "type" "fpmuldbl")
+ (set_attr "length" "8")])
+
+(define_split
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
+ (match_operand:SF 2 "register_operand" "f"))))
+ (set (match_operand:SF 3 "register_operand" "=&f")
+ (mult:SF (match_dup 1) (match_dup 2)))]
+ "! TARGET_SOFT_FLOAT && TARGET_PA_20"
+ [(set (match_dup 3) (mult:SF (match_dup 1) (match_dup 2)))
+ (set (match_dup 0) (neg:SF (mult:SF (match_dup 1) (match_dup 2))))]
+ "")
+
+;; Now fused multiplies with the result of the multiply negated.
+(define_insn ""
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
+ (match_operand:DF 2 "register_operand" "f")))
+ (match_operand:DF 3 "register_operand" "f")))]
+ "! TARGET_SOFT_FLOAT && TARGET_PA_20"
+ "fmpynfadd,dbl %1,%2,%3,%0"
+ [(set_attr "type" "fpmuldbl")
+ (set_attr "length" "4")])
+
+(define_insn ""
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
+ (match_operand:SF 2 "register_operand" "f")))
+ (match_operand:SF 3 "register_operand" "f")))]
+ "! TARGET_SOFT_FLOAT && TARGET_PA_20"
+ "fmpynfadd,sgl %1,%2,%3,%0"
+ [(set_attr "type" "fpmuldbl")
+ (set_attr "length" "4")])
+
+(define_insn ""
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
+ (match_operand:DF 2 "register_operand" "f")))
+ (match_operand:DF 3 "register_operand" "f")))
+ (set (match_operand:DF 4 "register_operand" "=&f")
+ (mult:DF (match_dup 1) (match_dup 2)))]
+ "! TARGET_SOFT_FLOAT && TARGET_PA_20"
+ "#"
+ [(set_attr "type" "fpmuldbl")
+ (set_attr "length" "8")])
+
+(define_split
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
+ (match_operand:DF 2 "register_operand" "f")))
+ (match_operand:DF 3 "register_operand" "f")))
+ (set (match_operand:DF 4 "register_operand" "=&f")
+ (mult:DF (match_dup 1) (match_dup 2)))]
+ "! TARGET_SOFT_FLOAT && TARGET_PA_20"
+ [(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2)))
+ (set (match_dup 0) (plus:DF (neg:DF (mult:DF (match_dup 1) (match_dup 2)))
+ (match_dup 3)))]
+ "")
+
+(define_insn ""
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
+ (match_operand:SF 2 "register_operand" "f")))
+ (match_operand:SF 3 "register_operand" "f")))
+ (set (match_operand:SF 4 "register_operand" "=&f")
+ (mult:SF (match_dup 1) (match_dup 2)))]
+ "! TARGET_SOFT_FLOAT && TARGET_PA_20"
+ "#"
+ [(set_attr "type" "fpmuldbl")
+ (set_attr "length" "8")])
+
+(define_split
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
+ (match_operand:SF 2 "register_operand" "f")))
+ (match_operand:SF 3 "register_operand" "f")))
+ (set (match_operand:SF 4 "register_operand" "=&f")
+ (mult:SF (match_dup 1) (match_dup 2)))]
+ "! TARGET_SOFT_FLOAT && TARGET_PA_20"
+ [(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2)))
+ (set (match_dup 0) (plus:SF (neg:SF (mult:SF (match_dup 1) (match_dup 2)))
+ (match_dup 3)))]
+ "")
+
+(define_insn ""
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (minus:DF (match_operand:DF 3 "register_operand" "f")
+ (mult:DF (match_operand:DF 1 "register_operand" "f")
+ (match_operand:DF 2 "register_operand" "f"))))
+ (set (match_operand:DF 4 "register_operand" "=&f")
+ (mult:DF (match_dup 1) (match_dup 2)))]
+ "! TARGET_SOFT_FLOAT && TARGET_PA_20"
+ "#"
+ [(set_attr "type" "fpmuldbl")
+ (set_attr "length" "8")])
+
+(define_split
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (minus:DF (match_operand:DF 3 "register_operand" "f")
+ (mult:DF (match_operand:DF 1 "register_operand" "f")
+ (match_operand:DF 2 "register_operand" "f"))))
+ (set (match_operand:DF 4 "register_operand" "=&f")
+ (mult:DF (match_dup 1) (match_dup 2)))]
+ "! TARGET_SOFT_FLOAT && TARGET_PA_20"
+ [(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2)))
+ (set (match_dup 0) (minus:DF (match_dup 3)
+ (mult:DF (match_dup 1) (match_dup 2))))]
+ "")
+
+(define_insn ""
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (minus:SF (match_operand:SF 3 "register_operand" "f")
+ (mult:SF (match_operand:SF 1 "register_operand" "f")
+ (match_operand:SF 2 "register_operand" "f"))))
+ (set (match_operand:SF 4 "register_operand" "=&f")
+ (mult:SF (match_dup 1) (match_dup 2)))]
+ "! TARGET_SOFT_FLOAT && TARGET_PA_20"
+ "#"
+ [(set_attr "type" "fpmuldbl")
+ (set_attr "length" "8")])
+
+(define_split
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (minus:SF (match_operand:SF 3 "register_operand" "f")
+ (mult:SF (match_operand:SF 1 "register_operand" "f")
+ (match_operand:SF 2 "register_operand" "f"))))
+ (set (match_operand:SF 4 "register_operand" "=&f")
+ (mult:SF (match_dup 1) (match_dup 2)))]
+ "! TARGET_SOFT_FLOAT && TARGET_PA_20"
+ [(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2)))
+ (set (match_dup 0) (minus:SF (match_dup 3)
+ (mult:SF (match_dup 1) (match_dup 2))))]
+ "")
+
+(define_insn ""
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))
+ (set (match_operand:DF 2 "register_operand" "=&f") (abs:DF (match_dup 1)))]
+ "! TARGET_SOFT_FLOAT && TARGET_PA_20"
+ "#"
+ [(set_attr "type" "fpalu")
+ (set_attr "length" "8")])
+
+(define_split
+ [(set (match_operand:DF 0 "register_operand" "=f")
+ (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))
+ (set (match_operand:DF 2 "register_operand" "=&f") (abs:DF (match_dup 1)))]
+ "! TARGET_SOFT_FLOAT && TARGET_PA_20"
+ [(set (match_dup 2) (abs:DF (match_dup 1)))
+ (set (match_dup 0) (neg:DF (abs:DF (match_dup 1))))]
+ "")
+
+(define_insn ""
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))
+ (set (match_operand:SF 2 "register_operand" "=&f") (abs:SF (match_dup 1)))]
+ "! TARGET_SOFT_FLOAT && TARGET_PA_20"
+ "#"
+ [(set_attr "type" "fpalu")
+ (set_attr "length" "8")])
+
+(define_split
+ [(set (match_operand:SF 0 "register_operand" "=f")
+ (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))
+ (set (match_operand:SF 2 "register_operand" "=&f") (abs:SF (match_dup 1)))]
+ "! TARGET_SOFT_FLOAT && TARGET_PA_20"
+ [(set (match_dup 2) (abs:SF (match_dup 1)))
+ (set (match_dup 0) (neg:SF (abs:SF (match_dup 1))))]
+ "")
;;- Shift instructions