OSDN Git Service

* pa.md (fused multiply): Add variants which reduce height for the
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 22 Sep 1999 20:24:45 +0000 (20:24 +0000)
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 22 Sep 1999 20:24:45 +0000 (20:24 +0000)
        fused multiply, but which still generate 2 insns.
        (fnegabs): Similarly.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@29598 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/pa/pa.md

index 6cd7f82..982be6d 100644 (file)
@@ -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'.
index 545d13a..6e98c95 100644 (file)
   [(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))))]
+  "")
 \f
 ;;- Shift instructions