[PATCH] S/390: DFP support 2/4: Add FP addon instructions

Andreas Krebbel krebbel1@de.ibm.com
Fri Mar 16 19:46:00 GMT 2007


Hi,

the second patch adds support for a few instructions which come with the z9-ec
as well but are not directly related to dfp.  These instructions
allow several sign bit operations without clobbering the condition code.
Another instruction was added which allows us to directly copy between
fprs and gprs - reducing the need of secondary memory locations.
The attached patch only draws advantage of this for 64 bit values.
Support for other modes can be provided adding splitters - what I've
postponed to a later addon patch.  (Note: For 4 byte modes it is not as 
easy as it might look from a first glance since fprs and gprs on s390 
use different byte ordering.)

Bootstrapped on s390 and s390x.
No testsuite regression occured.

OK for mainline?

Bye,

-Andreas-


2007-03-16  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.


Index: gcc/config/s390/s390.md
===================================================================
*** gcc/config/s390/s390.md.orig	2007-03-15 17:33:49.000000000 +0100
--- gcc/config/s390/s390.md	2007-03-16 09:43:37.000000000 +0100
***************
*** 97,102 ****
--- 97,105 ----
     ; Stack Smashing Protector
     (UNSPEC_SP_SET 		700)
     (UNSPEC_SP_TEST		701)
+ 
+    ; Copy sign instructions
+    (UNSPEC_COPYSIGN             800)
   ])
  
  ;;
***************
*** 149,155 ****
  ;; 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"
    (const_string "NN"))
  
  ;; Instruction type attribute used for scheduling.
--- 152,158 ----
  ;; 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,RRF"
    (const_string "NN"))
  
  ;; Instruction type attribute used for scheduling.
***************
*** 270,275 ****
--- 273,286 ----
  ;; 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.
***************
*** 885,890 ****
--- 896,939 ----
     [(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")
***************
*** 1575,1583 ****
    ""
    "")
  
  (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"))]
    "TARGET_64BIT"
    "@
     lzdr\t%0
--- 1624,1655 ----
    ""
    "")
  
+ (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"))]
    "TARGET_64BIT"
    "@
     lzdr\t%0
***************
*** 5971,5976 ****
--- 6043,6057 ----
    [(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")
***************
*** 6085,6090 ****
--- 6166,6180 ----
    [(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")
***************
*** 6191,6196 ****
--- 6281,6295 ----
    [(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")
***************
*** 6202,6207 ****
--- 6301,6321 ----
     (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.
  ;;
  
Index: gcc/config/s390/s390.h
===================================================================
*** gcc/config/s390/s390.h.orig	2007-03-16 09:21:37.000000000 +0100
--- gcc/config/s390/s390.h	2007-03-16 09:33:26.000000000 +0100
*************** extern const enum reg_class regclass_map
*** 476,482 ****
  
  /* 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))
  
  /* 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.  */
--- 476,484 ----
  
  /* 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)     \
!   && (!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.  */



More information about the Gcc-patches mailing list