s390.md (UNSPEC_COPYSIGN): New constant.
authorAndreas Krebbel <krebbel1@de.ibm.com>
Mon, 19 Mar 2007 08:48:36 +0000 (08:48 +0000)
committerAndreas Krebbel <krebbel@gcc.gnu.org>
Mon, 19 Mar 2007 08:48:36 +0000 (08:48 +0000)
2007-03-19  Andreas Krebbel  <krebbel1@de.ibm.com>

* config/s390/s390.md (UNSPEC_COPYSIGN): New constant.
(op_type attribute): RRF instruction type added.
(fT0): New mode attribute.
("*movdi_64dfp", "*movdf_64dfp", "*neg<mode>2_nocc", "*abs<mode>2_nocc",
"*negabs<mode>2_nocc", "copysign<mode>3"): Insn definitions added.
* config/s390/s390.h (SECONDARY_MEMORY_NEEDED): Due to a new instruction
no secondary memory is needed when moving DFmode values between GPRs
and FPRs.

From-SVN: r123056

gcc/ChangeLog
gcc/config/s390/s390.h
gcc/config/s390/s390.md

index 1d4e1278bb97a613541fb8251a96f4889606b70a..f2671f07d74183631761fa729e18caefc9dc2c71 100644 (file)
@@ -1,3 +1,14 @@
+2007-03-19  Andreas Krebbel  <krebbel1@de.ibm.com>
+
+       * config/s390/s390.md (UNSPEC_COPYSIGN): New constant.
+       (op_type attribute): RRF instruction type added.
+       (fT0): New mode attribute.
+       ("*movdi_64dfp", "*movdf_64dfp", "*neg<mode>2_nocc", "*abs<mode>2_nocc",
+       "*negabs<mode>2_nocc", "copysign<mode>3"): Insn definitions added.
+       * config/s390/s390.h (SECONDARY_MEMORY_NEEDED): Due to a new instruction
+       no secondary memory is needed when moving DFmode values between GPRs
+       and FPRs.
+
 2007-03-19  Andreas Krebbel  <krebbel1@de.ibm.com>
 
        * config/s390/s390.opt ("mhard-float", "msoft-float"): Bit value
index ba7a036e1ec30b3bfddb65c7bdbe22bf29eff1ec..fc36baf7cb1fb9752854ba5f5b53b510440155f4 100644 (file)
@@ -51,7 +51,8 @@ enum processor_flags
   PF_IEEE_FLOAT = 1,
   PF_ZARCH = 2,
   PF_LONG_DISPLACEMENT = 4,
-  PF_EXTIMM = 8
+  PF_EXTIMM = 8,
+  PF_DFP = 16
 };
 
 extern enum processor_type s390_tune;
@@ -68,11 +69,15 @@ extern enum processor_flags s390_arch_flags;
        (s390_arch_flags & PF_LONG_DISPLACEMENT)
 #define TARGET_CPU_EXTIMM \
        (s390_arch_flags & PF_EXTIMM)
+#define TARGET_CPU_DFP \
+       (s390_arch_flags & PF_DFP)
 
 #define TARGET_LONG_DISPLACEMENT \
        (TARGET_ZARCH && TARGET_CPU_LONG_DISPLACEMENT)
 #define TARGET_EXTIMM \
        (TARGET_ZARCH && TARGET_CPU_EXTIMM)
+#define TARGET_DFP \
+       (TARGET_ZARCH && TARGET_CPU_DFP)
 
 /* Run-time target specification.  */
 
@@ -103,9 +108,9 @@ extern enum processor_flags s390_arch_flags;
 #define TARGET_IEEE_FLOAT          1
 
 #ifdef DEFAULT_TARGET_64BIT
-#define TARGET_DEFAULT             (MASK_64BIT | MASK_ZARCH | MASK_HARD_FLOAT)
+#define TARGET_DEFAULT             (MASK_64BIT | MASK_ZARCH)
 #else
-#define TARGET_DEFAULT             MASK_HARD_FLOAT
+#define TARGET_DEFAULT             0
 #endif
 
 /* Support for configure-time defaults.  */
@@ -471,7 +476,9 @@ extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER];
 
 /* We need secondary memory to move data between GPRs and FPRs.  */
 #define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
- ((CLASS1) != (CLASS2) && ((CLASS1) == FP_REGS || (CLASS2) == FP_REGS))
+ ((CLASS1) != (CLASS2)                                \
+  && ((CLASS1) == FP_REGS || (CLASS2) == FP_REGS)     \
+  && (!TARGET_DFP || GET_MODE_SIZE (MODE) != 8))
 
 /* Get_secondary_mem widens its argument to BITS_PER_WORD which loses on 64bit
    because the movsi and movsf patterns don't handle r/f moves.  */
index 5f38f09298534c93e85e95ce96d835f88d8c2560..fbb2f9ad9fecd62aa8c9c838f056fa33fbf8fb83 100644 (file)
@@ -97,6 +97,9 @@
    ; Stack Smashing Protector
    (UNSPEC_SP_SET              700)
    (UNSPEC_SP_TEST             701)
+
+   ; Copy sign instructions
+   (UNSPEC_COPYSIGN             800)
  ])
 
 ;;
 ;; Used to determine defaults for length and other attribute values.
 
 (define_attr "op_type"
-  "NN,E,RR,RRE,RX,RS,RSI,RI,SI,S,SS,SSE,RXE,RSE,RIL,RIE,RXY,RSY,SIY"
+  "NN,E,RR,RRE,RX,RS,RSI,RI,SI,S,SS,SSE,RXE,RSE,RIL,RIE,RXY,RSY,SIY,RRF"
   (const_string "NN"))
 
 ;; Instruction type attribute used for scheduling.
 ;; This is used to disable the memory alternative in TFmode patterns.
 (define_mode_attr Rf [(TF "f") (DF "R") (SF "R")])
 
+;; This attribute is used in the operand constraint list
+;; for instructions dealing with the sign bit of 32 or 64bit fp values.
+;; TFmode values are represented by a fp register pair.  Since the
+;; sign bit instructions only handle single source and target fp registers
+;; these instructions can only be used for TFmode values if the source and
+;; target operand uses the same fp register.
+(define_mode_attr fT0 [(TF "0") (DF "f") (SF "f")])
+
 ;; In GPR and P templates, a constraint like "<d0>" will expand to "d" in DImode
 ;; and "0" in SImode. This allows to combine instructions of which the 31bit
 ;; version only operates on one register.
    [(set_attr "op_type" "RIL")
     (set_attr "type"    "larl")])
 
+(define_insn "*movdi_64dfp"
+  [(set (match_operand:DI 0 "nonimmediate_operand"
+                            "=d,d,d,d,d,d,d,d,f,d,d,d,d,
+                             m,!*f,!*f,!*f,!R,!T,d,t,Q,t,?Q")
+        (match_operand:DI 1 "general_operand"
+                            "K,N0HD0,N1HD0,N2HD0,N3HD0,Os,N0SD0,N1SD0,d,f,L,d,m,
+                             d,*f,R,T,*f,*f,t,d,t,Q,?Q"))]
+  "TARGET_64BIT && TARGET_DFP"
+  "@
+   lghi\t%0,%h1
+   llihh\t%0,%i1
+   llihl\t%0,%i1
+   llilh\t%0,%i1
+   llill\t%0,%i1
+   lgfi\t%0,%1
+   llihf\t%0,%k1
+   llilf\t%0,%k1
+   ldgr\t%0,%1
+   lgdr\t%0,%1
+   lay\t%0,%a1
+   lgr\t%0,%1
+   lg\t%0,%1
+   stg\t%1,%0
+   ldr\t%0,%1
+   ld\t%0,%1
+   ldy\t%0,%1
+   std\t%1,%0
+   stdy\t%1,%0
+   #
+   #
+   stam\t%1,%N1,%S0
+   lam\t%0,%N0,%S1
+   #"
+  [(set_attr "op_type" "RI,RI,RI,RI,RI,RIL,RIL,RIL,RRE,RRE,RXY,RRE,RXY,RXY,
+                        RR,RX,RXY,RX,RXY,*,*,RS,RS,SS")
+   (set_attr "type" "*,*,*,*,*,*,*,*,floaddf,floaddf,la,lr,load,store,
+                     floaddf,floaddf,floaddf,fstoredf,fstoredf,*,*,*,*,*")])
+
 (define_insn "*movdi_64extimm"
   [(set (match_operand:DI 0 "nonimmediate_operand"
                             "=d,d,d,d,d,d,d,d,d,d,d,m,!*f,!*f,!*f,!R,!T,d,t,Q,t,?Q")
   ""
   "")
 
+(define_insn "*movdf_64dfp"
+  [(set (match_operand:DF 0 "nonimmediate_operand"
+                           "=f,f,f,d,f,f,R,T,d,d,m,?Q")
+        (match_operand:DF 1 "general_operand"
+                           "G,f,d,f,R,T,f,f,d,m,d,?Q"))]
+  "TARGET_64BIT && TARGET_DFP"
+  "@
+   lzdr\t%0
+   ldr\t%0,%1
+   ldgr\t%0,%1
+   lgdr\t%0,%1
+   ld\t%0,%1
+   ldy\t%0,%1
+   std\t%1,%0
+   stdy\t%1,%0
+   lgr\t%0,%1
+   lg\t%0,%1
+   stg\t%1,%0
+   #"
+  [(set_attr "op_type" "RRE,RR,RRE,RRE,RX,RXY,RX,RXY,RRE,RXY,RXY,SS")
+   (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,floaddf,floaddf,
+                     fstoredf,fstoredf,lr,load,store,*")])
+
 (define_insn "*movdf_64"
   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,m,?Q")
-        (match_operand:DF 1 "general_operand" "G,f,R,T,f,f,d,m,d,?Q"))]
+        (match_operand:DF 1 "general_operand"       "G,f,R,T,f,f,d,m,d,?Q"))]
   "TARGET_64BIT"
   "@
    lzdr\t%0
   [(set_attr "op_type"  "RRE")
    (set_attr "type"     "fsimp<mode>")])
 
+; lcdfr
+(define_insn "*neg<mode>2_nocc"
+  [(set (match_operand:FPR 0 "register_operand"          "=f")
+        (neg:FPR (match_operand:FPR 1 "register_operand" "<fT0>")))]
+  "TARGET_HARD_FLOAT && TARGET_DFP"
+  "lcdfr\t%0,%1"
+  [(set_attr "op_type"  "RRE")
+   (set_attr "type"     "fsimp<mode>")])
+
 ; lcxbr, lcdbr, lcebr
 (define_insn "*neg<mode>2"
   [(set (match_operand:FPR 0 "register_operand" "=f")
   [(set_attr "op_type"  "RRE")
    (set_attr "type"     "fsimp<mode>")])
 
+; lpdfr
+(define_insn "*abs<mode>2_nocc"
+  [(set (match_operand:FPR 0 "register_operand"          "=f")
+        (abs:FPR (match_operand:FPR 1 "register_operand" "<fT0>")))]
+  "TARGET_HARD_FLOAT && TARGET_DFP"
+  "lpdfr\t%0,%1"
+  [(set_attr "op_type"  "RRE")
+   (set_attr "type"     "fsimp<mode>")])
+
 ; lpxbr, lpdbr, lpebr
 (define_insn "*abs<mode>2"
   [(set (match_operand:FPR 0 "register_operand" "=f")
   [(set_attr "op_type"  "RRE")
    (set_attr "type"     "fsimp<mode>")])
 
+; lndfr
+(define_insn "*negabs<mode>2_nocc"
+  [(set (match_operand:FPR 0 "register_operand"                   "=f")
+        (neg:FPR (abs:FPR (match_operand:FPR 1 "register_operand" "<fT0>"))))]
+  "TARGET_HARD_FLOAT && TARGET_DFP"
+  "lndfr\t%0,%1"
+  [(set_attr "op_type"  "RRE")
+   (set_attr "type"     "fsimp<mode>")])
+
 ; lnxbr, lndbr, lnebr
 (define_insn "*negabs<mode>2"
   [(set (match_operand:FPR 0 "register_operand" "=f")
   [(set_attr "op_type"  "RRE")
    (set_attr "type"     "fsimp<mode>")])
 
+;;
+;;- Copy sign instructions
+;;
+
+; cpsdr
+(define_insn "copysign<mode>3"
+  [(set (match_operand:FPR 0 "register_operand" "=f")
+       (unspec:FPR [(match_operand:FPR 1 "register_operand" "<fT0>")
+                    (match_operand:FPR 2 "register_operand" "f")] 
+                   UNSPEC_COPYSIGN))]
+  "TARGET_HARD_FLOAT && TARGET_DFP"
+  "cpsdr\t%0,%2,%1"
+  [(set_attr "op_type"  "RRF")
+   (set_attr "type"     "fsimp<mode>")])
+
 ;;
 ;;- Square root instructions.
 ;;