From 9a40d6bc0c227843acdae95248f17fc8c7bf81e6 Mon Sep 17 00:00:00 2001 From: Jeffrey A Law Date: Wed, 22 Sep 1999 20:24:45 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 4 + gcc/config/pa/pa.md | 280 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 284 insertions(+) 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 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 -- 2.7.4