[PATCH] S/390: DFP support 4/4: Add the DFP instruction support

Andreas Krebbel krebbel1@de.ibm.com
Fri Mar 16 20:56:00 GMT 2007


Hi,

the fourth patch finally adds the support for the hardware dfp instructions.

Bootstrapped on s390 and s390x.
No testsuite regression occured.
Tested on s390x with the dectest suite.

OK for mainline?

Bye,

-Andreas-


2007-03-16  Andreas Krebbel  <krebbel1@de.ibm.com>

	* config/s390/s390.md (op_type attribute): RRR instruction type added.
	(FP, DFP, SD_SF, DD_DF, TD_TF): New mode macros.
	(xde, xdee): Mode attributes adjusted to support DFP modes.
	(RRer, f0, op1, Rf, bt, bfp, HALF_TMODE): New mode attributes added.
	("cmp<mode>", "*cmp<mode>_css_0", "*cmp<mode>_ccs", TF move splitters,
	DF move splitters, "floatdi<mode>2", "add<mode>3", "*add<mode>3", 
	"*add<mode>3_cc", "*add<mode>3_cconly", "sub<mode>3", "*sub<mode>3",
	"*sub<mode>3_cc", "*sub<mode>3_cconly", "mul<mode>3", "*mul<mode>3",
	"div<mode>3", "*div<mode>3", "*neg<mode>2_nocc", "*abs<mode>2_nocc",
	"*negabs<mode>2_nocc", "copysign<mode>3"): Adjusted to support DFP 
	numbers.
	("*movtf_64", "*movtf_31", "*movdf_64dfp", "*movdf_64", "*movdf_31",
	"movsf"): Insn definitions removed.
	("*mov<mode>_64", "*mov<mode>_31", "mov<mode>", "*mov<mode>_64dfp",
	"*mov<mode>_64", "*mov<mode>_31", "fix_trunc<DFP:mode>di2",
	"trunctddd2", "truncddsd2", "extendddtd2", "extendsddd2"): Insn
	definitions added.
	("fixuns_truncdddi2", "fixuns_trunctddi2", "mov<mode>",
	"reload_in<mode>", "reload_out<mode>"): Expander added.
	("movtf", "movdf", "reload_outtf", "reload_outdf", "reload_intf"):
	Expander removed.


Index: gcc/config/s390/s390.md
===================================================================
*** gcc/config/s390/s390.md.orig	2007-03-16 09:43:50.000000000 +0100
--- gcc/config/s390/s390.md	2007-03-16 10:11:47.000000000 +0100
***************
*** 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.
--- 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,RRR"
    (const_string "NN"))
  
  ;; Instruction type attribute used for scheduling.
***************
*** 214,221 ****
--- 214,226 ----
  
  ;; This mode macro allows floating point patterns to be generated from the
  ;; same template.
+ (define_mode_macro FP [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")])
  (define_mode_macro BFP [TF DF SF])
+ (define_mode_macro DFP [TD DD])
  (define_mode_macro DSF [DF SF])
+ (define_mode_macro SD_SF [SF SD])
+ (define_mode_macro DD_DF [DF DD])
+ (define_mode_macro TD_TF [TF TD])
  
  ;; These mode macros allow 31-bit and 64-bit TDSI patterns to be generated
  ;; from the same template.
***************
*** 255,277 ****
  (define_code_attr atomic [(and "and") (ior "ior") (xor "xor") 
  			  (plus "add") (minus "sub") (mult "nand")])
  
  
! ;; In BFP templates, a string like "lt<de>br" will expand to "ltxbr" in TFmode,
! ;; "ltdbr" in DFmode, and "ltebr" in SFmode.
! (define_mode_attr xde [(TF "x") (DF "d") (SF "e")])
! 
! ;; In BFP templates, a string like "m<dee>br" will expand to "mxbr" in TFmode,
! ;; "mdbr" in DFmode, and "meebr" in SFmode.
! (define_mode_attr xdee [(TF "x") (DF "d") (SF "ee")])
! 
! ;; In BFP templates, "<RRe>" will expand to "RRE" in TFmode and "RR" otherwise.
  ;; Likewise for "<RXe>".
  (define_mode_attr RRe [(TF "RRE") (DF "RR") (SF "RR")])
  (define_mode_attr RXe [(TF "RXE") (DF "RX") (SF "RX")])
  
! ;; In BFP templates, "<Rf>" will expand to "f" in TFmode and "R" otherwise.
! ;; 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.
--- 260,296 ----
  (define_code_attr atomic [(and "and") (ior "ior") (xor "xor") 
  			  (plus "add") (minus "sub") (mult "nand")])
  
+ ;; In FP templates, a string like "lt<de>br" will expand to "ltxbr" in 
+ ;; TF/TDmode, "ltdbr" in DF/DDmode, and "ltebr" in SF/SDmode.
+ (define_mode_attr xde [(TF "x") (DF "d") (SF "e") (TD "x") (DD "d") (SD "e")])
+ 
+ ;; In FP templates, a <dee> in "m<dee><bt>r" will expand to "mx<bt>r" in 
+ ;; TF/TDmode, "md<bt>r" in DF/DDmode, "mee<bt>r" in SFmode and "me<bt>r in 
+ ;; SDmode.
+ (define_mode_attr xdee [(TF "x") (DF "d") (SF "ee") (TD "x") (DD "d") (SD "e")])
  
! ;; In FP templates, "<RRe>" will expand to "RRE" in TFmode and "RR" otherwise.
  ;; Likewise for "<RXe>".
  (define_mode_attr RRe [(TF "RRE") (DF "RR") (SF "RR")])
  (define_mode_attr RXe [(TF "RXE") (DF "RX") (SF "RX")])
  
! ;; The decimal floating point variants of add, sub, div and mul support 3
! ;; fp register operands.  The following macros allow to merge the bfp and
! ;; dfp variants in a single insn definition.
! 
! ;; This macro is used to set op_type accordingly.
! (define_mode_attr RRer [(TF "RRE") (DF "RRE") (SF "RRE") (TD "RRR") 
!                         (DD "RRR") (SD "RRR")])
! 
! ;; This macro is used in the operand constraint list in order to have the 
! ;; first and the second operand match for bfp modes.
! (define_mode_attr f0 [(TF "0") (DF "0") (SF "0") (TD "f") (DD "f") (DD "f")])
! 
! ;; This macro is used in the operand list of the instruction to have an 
! ;; additional operand for the dfp instructions.
! (define_mode_attr op1 [(TF "") (DF "") (SF "")
!                        (TD "%1,") (DD "%1,") (SD "%1,")])
! 
  
  ;; This attribute is used in the operand constraint list
  ;; for instructions dealing with the sign bit of 32 or 64bit fp values.
***************
*** 281,286 ****
--- 300,319 ----
  ;; target operand uses the same fp register.
  (define_mode_attr fT0 [(TF "0") (DF "f") (SF "f")])
  
+ ;; In FP templates, "<Rf>" will expand to "f" in TFmode and "R" otherwise.
+ ;; This is used to disable the memory alternative in TFmode patterns.
+ (define_mode_attr Rf [(TF "f") (DF "R") (SF "R") (TD "f") (DD "f") (SD "f")])
+ 
+ ;; This macro adds b for bfp instructions and t for dfp instructions and is used
+ ;; within instruction mnemonics.
+ (define_mode_attr bt [(TF "b") (DF "b") (SF "b") (TD "t") (DD "t") (SD "t")])
+ 
+ ;; Although it is unprecise for z9-ec we handle all dfp instructions like
+ ;; bfp regarding the pipeline description.
+ (define_mode_attr bfp [(TF "tf") (DF "df") (SF "sf")
+                        (TD "tf") (DD "df") (SD "sf")])
+ 
+ 
  ;; 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.
***************
*** 341,346 ****
--- 374,383 ----
  ;; in SImode.
  (define_mode_attr DBL [(DI "TI") (SI "DI")])
  
+ ;; This attribute expands to DF for TFmode and to DD for TDmode .  It is
+ ;; used for Txmode splitters splitting a Txmode copy into 2 Dxmode copies.
+ (define_mode_attr HALF_TMODE [(TF "DF") (TD "DD")])
+ 
  ;; Maximum unsigned integer that fits in MODE.
  (define_mode_attr max_uint [(HI "65535") (QI "255")])
  
***************
*** 362,369 ****
  
  (define_expand "cmp<mode>"
    [(set (reg:CC CC_REGNUM)
!         (compare:CC (match_operand:BFP 0 "register_operand" "")
!                     (match_operand:BFP 1 "general_operand" "")))]
    "TARGET_HARD_FLOAT"
  {
    s390_compare_op0 = operands[0];
--- 399,406 ----
  
  (define_expand "cmp<mode>"
    [(set (reg:CC CC_REGNUM)
!         (compare:CC (match_operand:FP 0 "register_operand" "")
!                     (match_operand:FP 1 "general_operand" "")))]
    "TARGET_HARD_FLOAT"
  {
    s390_compare_op0 = operands[0];
***************
*** 748,764 ****
  })
  
  
! ; (DF|SF) instructions
  
! ; ltxbr, ltdbr, ltebr
  (define_insn "*cmp<mode>_ccs_0"
    [(set (reg CC_REGNUM)
!         (compare (match_operand:BFP 0 "register_operand" "f")
!                  (match_operand:BFP 1 "const0_operand" "")))]
    "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
!   "lt<xde>br\t%0,%0"
     [(set_attr "op_type" "RRE")
!     (set_attr "type"  "fsimp<mode>")])
  
  ; ltxr, ltdr, lter
  (define_insn "*cmp<mode>_ccs_0_ibm"
--- 785,801 ----
  })
  
  
! ; (TF|DF|SF|TD|DD|SD) instructions
  
! ; ltxbr, ltdbr, ltebr, ltxtr, ltdtr
  (define_insn "*cmp<mode>_ccs_0"
    [(set (reg CC_REGNUM)
!         (compare (match_operand:FP 0 "register_operand" "f")
!                  (match_operand:FP 1 "const0_operand"   "")))]
    "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
!   "lt<xde><bt>r\t%0,%0"
     [(set_attr "op_type" "RRE")
!     (set_attr "type"  "fsimp<bfp>")])
  
  ; ltxr, ltdr, lter
  (define_insn "*cmp<mode>_ccs_0_ibm"
***************
*** 770,786 ****
     [(set_attr "op_type" "<RRe>")
      (set_attr "type"  "fsimp<mode>")])
  
! ; cxbr, cdbr, cebr, cxb, cdb, ceb
  (define_insn "*cmp<mode>_ccs"
    [(set (reg CC_REGNUM)
!         (compare (match_operand:BFP 0 "register_operand" "f,f")
!                  (match_operand:BFP 1 "general_operand" "f,<Rf>")))]
    "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
    "@
!    c<xde>br\t%0,%1
     c<xde>b\t%0,%1"
     [(set_attr "op_type" "RRE,RXE")
!     (set_attr "type"  "fsimp<mode>")])
  
  ; cxr, cdr, cer, cx, cd, ce
  (define_insn "*cmp<mode>_ccs_ibm"
--- 807,823 ----
     [(set_attr "op_type" "<RRe>")
      (set_attr "type"  "fsimp<mode>")])
  
! ; cxtr, cxbr, cdbr, cebr, cxb, cdb, ceb, cxbtr, cdbtr
  (define_insn "*cmp<mode>_ccs"
    [(set (reg CC_REGNUM)
!         (compare (match_operand:FP 0 "register_operand" "f,f")
!                  (match_operand:FP 1 "general_operand"  "f,<Rf>")))]
    "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
    "@
!    c<xde><bt>r\t%0,%1
     c<xde>b\t%0,%1"
     [(set_attr "op_type" "RRE,RXE")
!     (set_attr "type"  "fsimp<bfp>")])
  
  ; cxr, cdr, cer, cx, cd, ce
  (define_insn "*cmp<mode>_ccs_ibm"
***************
*** 1472,1489 ****
     (set_attr "type" "lr,load,load,*")])
  
  ;
! ; movtf instruction pattern(s).
  ;
  
! (define_expand "movtf"
!   [(set (match_operand:TF 0 "nonimmediate_operand" "")
!         (match_operand:TF 1 "general_operand"       ""))]
    ""
    "")
  
! (define_insn "*movtf_64"
!   [(set (match_operand:TF 0 "nonimmediate_operand" "=f,f,f,o,d,QS,d,o,Q")
!         (match_operand:TF 1 "general_operand"       "G,f,o,f,QS,d,dm,d,Q"))]
    "TARGET_64BIT"
    "@
     lzxr\t%0
--- 1509,1526 ----
     (set_attr "type" "lr,load,load,*")])
  
  ;
! ; mov(tf|td) instruction pattern(s).
  ;
  
! (define_expand "mov<mode>"
!   [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
!         (match_operand:TD_TF 1 "general_operand"      ""))]
    ""
    "")
  
! (define_insn "*mov<mode>_64"
!   [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o, d,QS, d,o,Q")
!         (match_operand:TD_TF 1 "general_operand"      " G,f,o,f,QS, d,dm,d,Q"))]
    "TARGET_64BIT"
    "@
     lzxr\t%0
***************
*** 1498,1506 ****
    [(set_attr "op_type" "RRE,RRE,*,*,RSY,RSY,*,*,*")
     (set_attr "type"    "fsimptf,fsimptf,*,*,lm,stm,*,*,*")])
  
! (define_insn "*movtf_31"
!   [(set (match_operand:TF 0 "nonimmediate_operand" "=f,f,f,o,Q")
!         (match_operand:TF 1 "general_operand"       "G,f,o,f,Q"))]
    "!TARGET_64BIT"
    "@
     lzxr\t%0
--- 1535,1543 ----
    [(set_attr "op_type" "RRE,RRE,*,*,RSY,RSY,*,*,*")
     (set_attr "type"    "fsimptf,fsimptf,*,*,lm,stm,*,*,*")])
  
! (define_insn "*mov<mode>_31"
!   [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o,Q")
!         (match_operand:TD_TF 1 "general_operand"      " G,f,o,f,Q"))]
    "!TARGET_64BIT"
    "@
     lzxr\t%0
***************
*** 1514,1555 ****
  ; TFmode in GPRs splitters
  
  (define_split
!   [(set (match_operand:TF 0 "nonimmediate_operand" "")
!         (match_operand:TF 1 "general_operand" ""))]
    "TARGET_64BIT && reload_completed
!    && s390_split_ok_p (operands[0], operands[1], TFmode, 0)"
    [(set (match_dup 2) (match_dup 4))
     (set (match_dup 3) (match_dup 5))]
  {
!   operands[2] = operand_subword (operands[0], 0, 0, TFmode);
!   operands[3] = operand_subword (operands[0], 1, 0, TFmode);
!   operands[4] = operand_subword (operands[1], 0, 0, TFmode);
!   operands[5] = operand_subword (operands[1], 1, 0, TFmode);
  })
  
  (define_split
!   [(set (match_operand:TF 0 "nonimmediate_operand" "")
!         (match_operand:TF 1 "general_operand" ""))]
    "TARGET_64BIT && reload_completed
!    && s390_split_ok_p (operands[0], operands[1], TFmode, 1)"
    [(set (match_dup 2) (match_dup 4))
     (set (match_dup 3) (match_dup 5))]
  {
!   operands[2] = operand_subword (operands[0], 1, 0, TFmode);
!   operands[3] = operand_subword (operands[0], 0, 0, TFmode);
!   operands[4] = operand_subword (operands[1], 1, 0, TFmode);
!   operands[5] = operand_subword (operands[1], 0, 0, TFmode);
  })
  
  (define_split
!   [(set (match_operand:TF 0 "register_operand" "")
!         (match_operand:TF 1 "memory_operand" ""))]
    "TARGET_64BIT && reload_completed
     && !FP_REG_P (operands[0])
     && !s_operand (operands[1], VOIDmode)"
    [(set (match_dup 0) (match_dup 1))]
  {
!   rtx addr = operand_subword (operands[0], 1, 0, DFmode);
    s390_load_address (addr, XEXP (operands[1], 0));
    operands[1] = replace_equiv_address (operands[1], addr);
  })
--- 1551,1592 ----
  ; TFmode in GPRs splitters
  
  (define_split
!   [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
!         (match_operand:TD_TF 1 "general_operand"      ""))]
    "TARGET_64BIT && reload_completed
!    && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
    [(set (match_dup 2) (match_dup 4))
     (set (match_dup 3) (match_dup 5))]
  {
!   operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
!   operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
!   operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
!   operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
  })
  
  (define_split
!   [(set (match_operand:TD_TF 0 "nonimmediate_operand" "")
!         (match_operand:TD_TF 1 "general_operand"      ""))]
    "TARGET_64BIT && reload_completed
!    && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
    [(set (match_dup 2) (match_dup 4))
     (set (match_dup 3) (match_dup 5))]
  {
!   operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
!   operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
!   operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
!   operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
  })
  
  (define_split
!   [(set (match_operand:TD_TF 0 "register_operand" "")
!         (match_operand:TD_TF 1 "memory_operand"   ""))]
    "TARGET_64BIT && reload_completed
     && !FP_REG_P (operands[0])
     && !s_operand (operands[1], VOIDmode)"
    [(set (match_dup 0) (match_dup 1))]
  {
!   rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
    s390_load_address (addr, XEXP (operands[1], 0));
    operands[1] = replace_equiv_address (operands[1], addr);
  })
***************
*** 1557,1593 ****
  ; TFmode in BFPs splitters
  
  (define_split
!   [(set (match_operand:TF 0 "register_operand" "")
!         (match_operand:TF 1 "memory_operand" ""))]
    "reload_completed && offsettable_memref_p (operands[1]) 
     && FP_REG_P (operands[0])"
    [(set (match_dup 2) (match_dup 4))
     (set (match_dup 3) (match_dup 5))]
  {
!   operands[2] = simplify_gen_subreg (DFmode, operands[0], TFmode, 0);
!   operands[3] = simplify_gen_subreg (DFmode, operands[0], TFmode, 8);
!   operands[4] = adjust_address_nv (operands[1], DFmode, 0);
!   operands[5] = adjust_address_nv (operands[1], DFmode, 8);
  })
  
  (define_split
!   [(set (match_operand:TF 0 "memory_operand" "")
!         (match_operand:TF 1 "register_operand" ""))]
    "reload_completed && offsettable_memref_p (operands[0])
     && FP_REG_P (operands[1])"
    [(set (match_dup 2) (match_dup 4))
     (set (match_dup 3) (match_dup 5))]
  {
!   operands[2] = adjust_address_nv (operands[0], DFmode, 0);
!   operands[3] = adjust_address_nv (operands[0], DFmode, 8);
!   operands[4] = simplify_gen_subreg (DFmode, operands[1], TFmode, 0);
!   operands[5] = simplify_gen_subreg (DFmode, operands[1], TFmode, 8);
  })
  
! (define_expand "reload_outtf"
!   [(parallel [(match_operand:TF 0 "" "")
!               (match_operand:TF 1 "register_operand" "f")
!               (match_operand:SI 2 "register_operand" "=&a")])]
    ""
  {
    rtx addr = gen_lowpart (Pmode, operands[2]);
--- 1594,1634 ----
  ; TFmode in BFPs splitters
  
  (define_split
!   [(set (match_operand:TD_TF 0 "register_operand" "")
!         (match_operand:TD_TF 1 "memory_operand" ""))]
    "reload_completed && offsettable_memref_p (operands[1]) 
     && FP_REG_P (operands[0])"
    [(set (match_dup 2) (match_dup 4))
     (set (match_dup 3) (match_dup 5))]
  {
!   operands[2] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
!                                      <MODE>mode, 0);
!   operands[3] = simplify_gen_subreg (<HALF_TMODE>mode, operands[0],
!                                      <MODE>mode, 8);
!   operands[4] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 0);
!   operands[5] = adjust_address_nv (operands[1], <HALF_TMODE>mode, 8);
  })
  
  (define_split
!   [(set (match_operand:TD_TF 0 "memory_operand" "")
!         (match_operand:TD_TF 1 "register_operand" ""))]
    "reload_completed && offsettable_memref_p (operands[0])
     && FP_REG_P (operands[1])"
    [(set (match_dup 2) (match_dup 4))
     (set (match_dup 3) (match_dup 5))]
  {
!   operands[2] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 0);
!   operands[3] = adjust_address_nv (operands[0], <HALF_TMODE>mode, 8);
!   operands[4] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
! 				     <MODE>mode, 0);
!   operands[5] = simplify_gen_subreg (<HALF_TMODE>mode, operands[1],
!                                      <MODE>mode, 8);
  })
  
! (define_expand "reload_out<mode>"
!   [(parallel [(match_operand:TD_TF 0 "" "")
!               (match_operand:TD_TF 1 "register_operand" "f")
!               (match_operand:SI 2    "register_operand" "=&a")])]
    ""
  {
    rtx addr = gen_lowpart (Pmode, operands[2]);
***************
*** 1599,1608 ****
    DONE;
  })
  
! (define_expand "reload_intf"
!   [(parallel [(match_operand:TF 0 "register_operand" "=f")
!               (match_operand:TF 1 "" "")
!               (match_operand:SI 2 "register_operand" "=&a")])]
    ""
  {
    rtx addr = gen_lowpart (Pmode, operands[2]);
--- 1640,1649 ----
    DONE;
  })
  
! (define_expand "reload_in<mode>"
!   [(parallel [(match_operand:TD_TF 0 "register_operand" "=f")
!               (match_operand:TD_TF 1 "" "")
!               (match_operand:SI 2    "register_operand" "=&a")])]
    ""
  {
    rtx addr = gen_lowpart (Pmode, operands[2]);
***************
*** 1615,1634 ****
  })
  
  ;
! ; movdf instruction pattern(s).
  ;
  
! (define_expand "movdf"
!   [(set (match_operand:DF 0 "nonimmediate_operand" "")
!         (match_operand:DF 1 "general_operand"  ""))]
    ""
    "")
  
! (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
--- 1656,1675 ----
  })
  
  ;
! ; mov(df|dd) instruction pattern(s).
  ;
  
! (define_expand "mov<mode>"
!   [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
!         (match_operand:DD_DF 1 "general_operand"  ""))]
    ""
    "")
  
! (define_insn "*mov<mode>_64dfp"
!   [(set (match_operand:DD_DF 0 "nonimmediate_operand"
! 			       "=f,f,f,d,f,f,R,T,d,d,m,?Q")
!         (match_operand:DD_DF 1 "general_operand"
! 			       "G,f,d,f,R,T,f,f,d,m,d,?Q"))]
    "TARGET_64BIT && TARGET_DFP"
    "@
     lzdr\t%0
***************
*** 1647,1655 ****
     (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
--- 1688,1696 ----
     (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,floaddf,floaddf,
                       fstoredf,fstoredf,lr,load,store,*")])
  
! (define_insn "*mov<mode>_64"
!   [(set (match_operand:DD_DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,m,?Q")
!         (match_operand:DD_DF 1 "general_operand"       "G,f,R,T,f,f,d,m,d,?Q"))]
    "TARGET_64BIT"
    "@
     lzdr\t%0
***************
*** 1663,1673 ****
     stg\t%1,%0
     #"
    [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RRE,RXY,RXY,SS")
!    (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,fstoredf,fstoredf,lr,load,store,*")])
  
! (define_insn "*movdf_31"
!   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,Q,S,d,o,Q")
!         (match_operand:DF 1 "general_operand" "G,f,R,T,f,f,Q,S,d,d,dPm,d,Q"))]
    "!TARGET_64BIT"
    "@
     lzdr\t%0
--- 1704,1717 ----
     stg\t%1,%0
     #"
    [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RRE,RXY,RXY,SS")
!    (set_attr "type" "fsimp<bfp>,fload<bfp>,fload<bfp>,fload<bfp>,
!                      fstore<bfp>,fstore<bfp>,lr,load,store,*")])
  
! (define_insn "*mov<mode>_31"
!   [(set (match_operand:DD_DF 0 "nonimmediate_operand"
!                                "=f,f,f,f,R,T,d,d,Q,S,  d,o,Q")
!         (match_operand:DD_DF 1 "general_operand"
!                                " G,f,R,T,f,f,Q,S,d,d,dPm,d,Q"))]
    "!TARGET_64BIT"
    "@
     lzdr\t%0
***************
*** 1684,1737 ****
     #
     #"
    [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RS,RSY,RS,RSY,*,*,SS")
!    (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,fstoredf,fstoredf,\
!                      lm,lm,stm,stm,*,*,*")])
  
  (define_split
!   [(set (match_operand:DF 0 "nonimmediate_operand" "")
!         (match_operand:DF 1 "general_operand" ""))]
    "!TARGET_64BIT && reload_completed
!    && s390_split_ok_p (operands[0], operands[1], DFmode, 0)"
    [(set (match_dup 2) (match_dup 4))
     (set (match_dup 3) (match_dup 5))]
  {
!   operands[2] = operand_subword (operands[0], 0, 0, DFmode);
!   operands[3] = operand_subword (operands[0], 1, 0, DFmode);
!   operands[4] = operand_subword (operands[1], 0, 0, DFmode);
!   operands[5] = operand_subword (operands[1], 1, 0, DFmode);
  })
  
  (define_split
!   [(set (match_operand:DF 0 "nonimmediate_operand" "")
!         (match_operand:DF 1 "general_operand" ""))]
    "!TARGET_64BIT && reload_completed
!    && s390_split_ok_p (operands[0], operands[1], DFmode, 1)"
    [(set (match_dup 2) (match_dup 4))
     (set (match_dup 3) (match_dup 5))]
  {
!   operands[2] = operand_subword (operands[0], 1, 0, DFmode);
!   operands[3] = operand_subword (operands[0], 0, 0, DFmode);
!   operands[4] = operand_subword (operands[1], 1, 0, DFmode);
!   operands[5] = operand_subword (operands[1], 0, 0, DFmode);
  })
  
  (define_split
!   [(set (match_operand:DF 0 "register_operand" "")
!         (match_operand:DF 1 "memory_operand" ""))]
    "!TARGET_64BIT && reload_completed
     && !FP_REG_P (operands[0])
     && !s_operand (operands[1], VOIDmode)"
    [(set (match_dup 0) (match_dup 1))]
  {
!   rtx addr = operand_subword (operands[0], 1, 0, DFmode);
    s390_load_address (addr, XEXP (operands[1], 0));
    operands[1] = replace_equiv_address (operands[1], addr);
  })
  
! (define_expand "reload_outdf"
!   [(parallel [(match_operand:DF 0 "" "")
!               (match_operand:DF 1 "register_operand" "d")
!               (match_operand:SI 2 "register_operand" "=&a")])]
    "!TARGET_64BIT"
  {
    gcc_assert (MEM_P (operands[0]));
--- 1728,1781 ----
     #
     #"
    [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RS,RSY,RS,RSY,*,*,SS")
!    (set_attr "type" "fsimp<bfp>,fload<bfp>,fload<bfp>,fload<bfp>,
!                      fstore<bfp>,fstore<bfp>,lm,lm,stm,stm,*,*,*")])
  
  (define_split
!   [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
!         (match_operand:DD_DF 1 "general_operand" ""))]
    "!TARGET_64BIT && reload_completed
!    && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 0)"
    [(set (match_dup 2) (match_dup 4))
     (set (match_dup 3) (match_dup 5))]
  {
!   operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
!   operands[3] = operand_subword (operands[0], 1, 0, <MODE>mode);
!   operands[4] = operand_subword (operands[1], 0, 0, <MODE>mode);
!   operands[5] = operand_subword (operands[1], 1, 0, <MODE>mode);
  })
  
  (define_split
!   [(set (match_operand:DD_DF 0 "nonimmediate_operand" "")
!         (match_operand:DD_DF 1 "general_operand" ""))]
    "!TARGET_64BIT && reload_completed
!    && s390_split_ok_p (operands[0], operands[1], <MODE>mode, 1)"
    [(set (match_dup 2) (match_dup 4))
     (set (match_dup 3) (match_dup 5))]
  {
!   operands[2] = operand_subword (operands[0], 1, 0, <MODE>mode);
!   operands[3] = operand_subword (operands[0], 0, 0, <MODE>mode);
!   operands[4] = operand_subword (operands[1], 1, 0, <MODE>mode);
!   operands[5] = operand_subword (operands[1], 0, 0, <MODE>mode);
  })
  
  (define_split
!   [(set (match_operand:DD_DF 0 "register_operand" "")
!         (match_operand:DD_DF 1 "memory_operand" ""))]
    "!TARGET_64BIT && reload_completed
     && !FP_REG_P (operands[0])
     && !s_operand (operands[1], VOIDmode)"
    [(set (match_dup 0) (match_dup 1))]
  {
!   rtx addr = operand_subword (operands[0], 1, 0, <MODE>mode);
    s390_load_address (addr, XEXP (operands[1], 0));
    operands[1] = replace_equiv_address (operands[1], addr);
  })
  
! (define_expand "reload_out<mode>"
!   [(parallel [(match_operand:DD_DF 0 "" "")
!               (match_operand:DD_DF 1 "register_operand" "d")
!               (match_operand:SI 2    "register_operand" "=&a")])]
    "!TARGET_64BIT"
  {
    gcc_assert (MEM_P (operands[0]));
***************
*** 1742,1753 ****
  })
  
  ;
! ; movsf instruction pattern(s).
  ;
  
! (define_insn "movsf"
!   [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,d,R,T,?Q")
!         (match_operand:SF 1 "general_operand" "G,f,R,T,f,f,d,R,T,d,d,?Q"))]
    ""
    "@
     lzer\t%0
--- 1786,1799 ----
  })
  
  ;
! ; mov(sf|sd) instruction pattern(s).
  ;
  
! (define_insn "mov<mode>"
!   [(set (match_operand:SD_SF 0 "nonimmediate_operand"
! 			       "=f,f,f,f,R,T,d,d,d,R,T,?Q")
!         (match_operand:SD_SF 1 "general_operand"
! 			       " G,f,R,T,f,f,d,R,T,d,d,?Q"))]
    ""
    "@
     lzer\t%0
***************
*** 1763,1770 ****
     sty\t%1,%0
     #"
    [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RR,RX,RXY,RX,RXY,SS")
!    (set_attr "type" "fsimpsf,floadsf,floadsf,floadsf,fstoresf,fstoresf,
!                      lr,load,load,store,store,*")])
  
  ;
  ; movcc instruction pattern
--- 1809,1816 ----
     sty\t%1,%0
     #"
    [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RR,RX,RXY,RX,RXY,SS")
!    (set_attr "type" "fsimp<bfp>,fload<bfp>,fload<bfp>,fload<bfp>,
!                      fstore<bfp>,fstore<bfp>,lr,load,load,store,store,*")])
  
  ;
  ; movcc instruction pattern
***************
*** 3143,3151 ****
     (set (strict_low_part (match_dup 2)) (match_dup 1))]
    "operands[2] = gen_lowpart (QImode, operands[0]);")
  
  
  ;
! ; fixuns_trunc(sf|df)(si|di)2 and fix_trunc(sf|df)(si|di)2 instruction pattern(s).
  ;
  
  (define_expand "fixuns_trunc<BFP:mode><GPR:mode>2"
--- 3189,3264 ----
     (set (strict_low_part (match_dup 2)) (match_dup 1))]
    "operands[2] = gen_lowpart (QImode, operands[0]);")
  
+ ;
+ ; fixuns_trunc(dd|td)di2 instruction pattern(s).
+ ;
+ 
+ (define_expand "fixuns_truncdddi2"
+   [(parallel
+     [(set (match_operand:DI 0 "register_operand" "")
+ 	  (unsigned_fix:DI (match_operand:DD 1 "register_operand" "")))
+      (clobber (match_scratch:TD 2 "=f"))])]
+ 	      
+   "TARGET_HARD_FLOAT && TARGET_HARD_DFP"
+ {
+   rtx label1 = gen_label_rtx ();
+   rtx label2 = gen_label_rtx ();
+   rtx temp = gen_reg_rtx (TDmode);
+   REAL_VALUE_TYPE cmp, sub;
+ 
+   decimal_real_from_string (&cmp, "9223372036854775808.0");  /* 2^63 */
+   decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
+ 
+   /* 2^63 can't be represented as 64bit DFP number with full precision.  The
+      solution is doing the check and the subtraction in TD mode and using a 
+      TD -> DI convert afterwards.  */
+   emit_insn (gen_extendddtd2 (temp, operands[1]));
+   temp = force_reg (TDmode, temp);
+   emit_insn (gen_cmptd (temp,
+ 	CONST_DOUBLE_FROM_REAL_VALUE (cmp, TDmode)));
+   emit_jump_insn (gen_blt (label1));
+   emit_insn (gen_subtd3 (temp, temp,
+ 	CONST_DOUBLE_FROM_REAL_VALUE (sub, TDmode)));
+   emit_insn (gen_fix_trunctddi2 (operands[0], temp, GEN_INT(11)));
+   emit_jump (label2);
+ 
+   emit_label (label1);
+   emit_insn (gen_fix_truncdddi2 (operands[0], operands[1], GEN_INT(9)));
+   emit_label (label2);
+   DONE;
+ })
+ 
+ (define_expand "fixuns_trunctddi2"
+   [(set (match_operand:DI 0 "register_operand" "")
+         (unsigned_fix:DI (match_operand:TD 1 "register_operand" "")))]
+   "TARGET_HARD_FLOAT && TARGET_HARD_DFP"
+ {
+   rtx label1 = gen_label_rtx ();
+   rtx label2 = gen_label_rtx ();
+   rtx temp = gen_reg_rtx (TDmode);
+   REAL_VALUE_TYPE cmp, sub;
+   
+   operands[1] = force_reg (TDmode, operands[1]);
+   decimal_real_from_string (&cmp, "9223372036854775808.0");  /* 2^63 */
+   decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */
+   
+   emit_insn (gen_cmptd (operands[1],
+ 	CONST_DOUBLE_FROM_REAL_VALUE (cmp, TDmode)));
+   emit_jump_insn (gen_blt (label1));
+   emit_insn (gen_subtd3 (temp, operands[1],
+ 	CONST_DOUBLE_FROM_REAL_VALUE (sub, TDmode)));
+   emit_insn (gen_fix_trunctddi2 (operands[0], temp, GEN_INT(11)));
+   emit_jump (label2);
+ 
+   emit_label (label1);
+   emit_insn (gen_fix_trunctddi2 (operands[0], operands[1], GEN_INT(9)));
+   emit_label (label2);
+   DONE;
+ })
  
  ;
! ; fixuns_trunc(sf|df)(si|di)2 and fix_trunc(sf|df)(si|di)2 
! ; instruction pattern(s).
  ;
  
  (define_expand "fixuns_trunc<BFP:mode><GPR:mode>2"
***************
*** 3200,3205 ****
--- 3313,3335 ----
    [(set_attr "op_type" "RRE")
     (set_attr "type"    "ftoi")])
  
+ 
+ ;
+ ; fix_trunc(td|dd)di2 instruction pattern(s).
+ ;
+ 
+ ; cgxtr, cgdtr
+ (define_insn "fix_trunc<DFP:mode>di2"
+   [(set (match_operand:DI 0 "register_operand" "=d")
+         (fix:DI (match_operand:DFP 1 "register_operand" "f")))
+    (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] UNSPEC_ROUND)
+    (clobber (reg:CC CC_REGNUM))]
+   "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_HARD_DFP"
+   "cg<DFP:xde>tr\t%0,%h2,%1"
+   [(set_attr "op_type" "RRF")
+    (set_attr "type"    "ftoi")])
+ 
+ 
  ;
  ; fix_trunctf(si|di)2 instruction pattern(s).
  ;
***************
*** 3288,3299 ****
  ; float(si|di)(tf|df|sf)2 instruction pattern(s).
  ;
  
! ; cxgbr, cdgbr, cegbr
  (define_insn "floatdi<mode>2"
!   [(set (match_operand:BFP 0 "register_operand" "=f")
!         (float:BFP (match_operand:DI 1 "register_operand" "d")))]
    "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
!   "c<xde>gbr\t%0,%1"
    [(set_attr "op_type" "RRE")
     (set_attr "type"    "itof" )])
  
--- 3418,3429 ----
  ; float(si|di)(tf|df|sf)2 instruction pattern(s).
  ;
  
! ; cxgbr, cdgbr, cegbr, cxgtr, cdgtr
  (define_insn "floatdi<mode>2"
!   [(set (match_operand:FP 0 "register_operand" "=f")
!         (float:FP (match_operand:DI 1 "register_operand" "d")))]
    "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
!   "c<xde>g<bt>r\t%0,%1"
    [(set_attr "op_type" "RRE")
     (set_attr "type"    "itof" )])
  
***************
*** 3458,3463 ****
--- 3588,3613 ----
     (set_attr "type"   "ftrunctf")])
  
  ;
+ ; trunctddd2 and truncddsd2 instruction pattern(s).
+ ;
+ 
+ (define_insn "trunctddd2"
+   [(set (match_operand:DD 0 "register_operand" "=f")
+ 	(float_truncate:DD (match_operand:TD 1 "register_operand" "f")))]
+   "TARGET_HARD_FLOAT && TARGET_HARD_DFP"
+   "ldxtr\t%0,0,%1,0"
+   [(set_attr "op_type" "RRF")
+    (set_attr "type"    "fsimptf")])
+ 
+ (define_insn "truncddsd2"
+   [(set (match_operand:SD 0 "register_operand" "=f")
+ 	(float_truncate:SD (match_operand:DD 1 "register_operand" "f")))]
+   "TARGET_HARD_FLOAT && TARGET_HARD_DFP"
+   "ledtr\t%0,0,%1,0"
+   [(set_attr "op_type" "RRF")
+    (set_attr "type"    "fsimptf")])
+ 
+ ;
  ; extendsfdf2 instruction pattern(s).
  ;
  
***************
*** 3554,3559 ****
--- 3704,3728 ----
    [(set_attr "op_type"  "RRE,RXE")
     (set_attr "type"   "fsimptf, floadtf")])
  
+ ;
+ ; extendddtd2 and extendsddd2 instruction pattern(s).
+ ;
+ 
+ (define_insn "extendddtd2"
+   [(set (match_operand:TD 0 "register_operand" "=f")
+ 	(float_extend:TD (match_operand:DD 1 "register_operand" "f")))]
+   "TARGET_HARD_FLOAT && TARGET_HARD_DFP"
+   "lxdtr\t%0,%1,0"
+   [(set_attr "op_type" "RRF")
+    (set_attr "type"    "fsimptf")])
+ 
+ (define_insn "extendsddd2"
+   [(set (match_operand:DD 0 "register_operand" "=f")
+ 	(float_extend:DD (match_operand:SD 1 "register_operand" "f")))]
+   "TARGET_HARD_FLOAT && TARGET_HARD_DFP"
+   "ldetr\t%0,%1,0"
+   [(set_attr "op_type" "RRF")
+    (set_attr "type"    "fsimptf")])
  
  ;;
  ;; ARITHMETIC OPERATIONS
***************
*** 3878,3936 ****
    [(set_attr "op_type"  "RI,RIL")])
  
  ;
! ; add(df|sf)3 instruction pattern(s).
  ;
  
  (define_expand "add<mode>3"
    [(parallel
!     [(set (match_operand:BFP 0 "register_operand" "=f,f")
!           (plus:BFP (match_operand:BFP 1 "nonimmediate_operand" "%0,0")
!                     (match_operand:BFP 2 "general_operand" "f,<Rf>")))
       (clobber (reg:CC CC_REGNUM))])]
    "TARGET_HARD_FLOAT"
    "")
  
! ; axbr, adbr, aebr, axb, adb, aeb
  (define_insn "*add<mode>3"
!   [(set (match_operand:BFP 0 "register_operand" "=f,f")
!         (plus:BFP (match_operand:BFP 1 "nonimmediate_operand" "%0,0")
!                   (match_operand:BFP 2 "general_operand" "f,<Rf>")))
     (clobber (reg:CC CC_REGNUM))]
    "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
    "@
!    a<xde>br\t%0,%2
     a<xde>b\t%0,%2"
!   [(set_attr "op_type"  "RRE,RXE")
!    (set_attr "type"     "fsimp<mode>")])
  
! ; axbr, adbr, aebr, axb, adb, aeb
  (define_insn "*add<mode>3_cc"
    [(set (reg CC_REGNUM)
! 	(compare (plus:BFP (match_operand:BFP 1 "nonimmediate_operand" "%0,0")
! 			   (match_operand:BFP 2 "general_operand" "f,<Rf>"))
! 		 (match_operand:BFP 3 "const0_operand" "")))
!    (set (match_operand:BFP 0 "register_operand" "=f,f")
! 	(plus:BFP (match_dup 1) (match_dup 2)))]
    "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
    "@
!    a<xde>br\t%0,%2
     a<xde>b\t%0,%2"
!   [(set_attr "op_type"  "RRE,RXE")
!    (set_attr "type"     "fsimp<mode>")])
  
! ; axbr, adbr, aebr, axb, adb, aeb
  (define_insn "*add<mode>3_cconly"
    [(set (reg CC_REGNUM)
! 	(compare (plus:BFP (match_operand:BFP 1 "nonimmediate_operand" "%0,0")
! 			   (match_operand:BFP 2 "general_operand" "f,<Rf>"))
! 		 (match_operand:BFP 3 "const0_operand" "")))
!    (clobber (match_scratch:BFP 0 "=f,f"))]
    "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
    "@
!    a<xde>br\t%0,%2
     a<xde>b\t%0,%2"
!   [(set_attr "op_type"  "RRE,RXE")
!    (set_attr "type"     "fsimp<mode>")])
  
  ; axr, adr, aer, ax, ad, ae
  (define_insn "*add<mode>3_ibm"
--- 4047,4105 ----
    [(set_attr "op_type"  "RI,RIL")])
  
  ;
! ; add(tf|df|sf|td|dd)3 instruction pattern(s).
  ;
  
  (define_expand "add<mode>3"
    [(parallel
!     [(set (match_operand:FP 0 "register_operand" "")
!           (plus:FP (match_operand:FP 1 "nonimmediate_operand" "")
!                     (match_operand:FP 2 "general_operand" "")))
       (clobber (reg:CC CC_REGNUM))])]
    "TARGET_HARD_FLOAT"
    "")
  
! ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
  (define_insn "*add<mode>3"
!   [(set (match_operand:FP 0 "register_operand"              "=f,   f")
!         (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%<f0>,0")
! 		 (match_operand:FP 2 "general_operand"      " f,<Rf>")))
     (clobber (reg:CC CC_REGNUM))]
    "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
    "@
!    a<xde><bt>r\t%0,<op1>%2
     a<xde>b\t%0,%2"
!   [(set_attr "op_type"  "<RRer>,RXE")
!    (set_attr "type"     "fsimp<bfp>")])
  
! ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
  (define_insn "*add<mode>3_cc"
    [(set (reg CC_REGNUM)
! 	(compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%<f0>,0")
! 			  (match_operand:FP 2 "general_operand"      " f,<Rf>"))
! 		 (match_operand:FP 3 "const0_operand" "")))
!    (set (match_operand:FP 0 "register_operand" "=f,f")
! 	(plus:FP (match_dup 1) (match_dup 2)))]
    "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
    "@
!    a<xde><bt>r\t%0,<op1>%2
     a<xde>b\t%0,%2"
!   [(set_attr "op_type"  "<RRer>,RXE")
!    (set_attr "type"     "fsimp<bfp>")])
  
! ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr
  (define_insn "*add<mode>3_cconly"
    [(set (reg CC_REGNUM)
! 	(compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%<f0>,0")
! 			   (match_operand:FP 2 "general_operand"      " f,<Rf>"))
! 		 (match_operand:FP 3 "const0_operand" "")))
!    (clobber (match_scratch:FP 0 "=f,f"))]
    "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
    "@
!    a<xde><bt>r\t%0,<op1>%2
     a<xde>b\t%0,%2"
!   [(set_attr "op_type"  "<RRer>,RXE")
!    (set_attr "type"     "fsimp<bfp>")])
  
  ; axr, adr, aer, ax, ad, ae
  (define_insn "*add<mode>3_ibm"
***************
*** 4221,4279 ****
    [(set_attr "op_type"  "RR<E>,RX<Y>,RXY")])
  
  ;
! ; sub(df|sf)3 instruction pattern(s).
  ;
  
  (define_expand "sub<mode>3"
    [(parallel
!     [(set (match_operand:BFP 0 "register_operand" "=f,f")
!           (minus:BFP (match_operand:BFP 1 "register_operand" "0,0")
!                      (match_operand:BFP 2 "general_operand" "f,R")))
       (clobber (reg:CC CC_REGNUM))])]
    "TARGET_HARD_FLOAT"
    "")
  
! ; sxbr, sdbr, sebr, sxb, sdb, seb
  (define_insn "*sub<mode>3"
!   [(set (match_operand:BFP 0 "register_operand" "=f,f")
!         (minus:BFP (match_operand:BFP 1 "register_operand" "0,0")
!                    (match_operand:BFP 2 "general_operand" "f,<Rf>")))
     (clobber (reg:CC CC_REGNUM))]
    "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
    "@
!    s<xde>br\t%0,%2
     s<xde>b\t%0,%2"
!   [(set_attr "op_type"  "RRE,RXE")
!    (set_attr "type"     "fsimp<mode>")])
  
! ; sxbr, sdbr, sebr, sxb, sdb, seb
  (define_insn "*sub<mode>3_cc"
    [(set (reg CC_REGNUM)
! 	(compare (minus:BFP (match_operand:BFP 1 "nonimmediate_operand" "0,0")
! 			    (match_operand:BFP 2 "general_operand" "f,<Rf>"))
! 		 (match_operand:BFP 3 "const0_operand" "")))
!    (set (match_operand:BFP 0 "register_operand" "=f,f")
! 	(minus:BFP (match_dup 1) (match_dup 2)))]
    "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
    "@
!    s<xde>br\t%0,%2
     s<xde>b\t%0,%2"
!   [(set_attr "op_type"  "RRE,RXE")
!    (set_attr "type"     "fsimp<mode>")])
  
! ; sxbr, sdbr, sebr, sxb, sdb, seb
  (define_insn "*sub<mode>3_cconly"
    [(set (reg CC_REGNUM)
! 	(compare (minus:BFP (match_operand:BFP 1 "nonimmediate_operand" "0,0")
! 			    (match_operand:BFP 2 "general_operand" "f,<Rf>"))
! 		 (match_operand:BFP 3 "const0_operand" "")))
!    (clobber (match_scratch:BFP 0 "=f,f"))]
    "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
    "@
!    s<xde>br\t%0,%2
     s<xde>b\t%0,%2"
!   [(set_attr "op_type"  "RRE,RXE")
!    (set_attr "type"     "fsimp<mode>")])
  
  ; sxr, sdr, ser, sx, sd, se
  (define_insn "*sub<mode>3_ibm"
--- 4390,4448 ----
    [(set_attr "op_type"  "RR<E>,RX<Y>,RXY")])
  
  ;
! ; sub(tf|df|sf|td|dd)3 instruction pattern(s).
  ;
  
  (define_expand "sub<mode>3"
    [(parallel
!     [(set (match_operand:FP 0 "register_operand" "")
!           (minus:FP (match_operand:FP 1 "register_operand" "")
!                      (match_operand:FP 2 "general_operand" "")))
       (clobber (reg:CC CC_REGNUM))])]
    "TARGET_HARD_FLOAT"
    "")
  
! ; sxbr, sdbr, sebr, sxb, sdb, seb, sxtr, sdtr
  (define_insn "*sub<mode>3"
!   [(set (match_operand:FP 0 "register_operand"            "=f,  f")
!         (minus:FP (match_operand:FP 1 "register_operand" "<f0>,0")
!                    (match_operand:FP 2 "general_operand"  "f,<Rf>")))
     (clobber (reg:CC CC_REGNUM))]
    "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
    "@
!    s<xde><bt>r\t%0,<op1>%2
     s<xde>b\t%0,%2"
!   [(set_attr "op_type"  "<RRer>,RXE")
!    (set_attr "type"     "fsimp<bfp>")])
  
! ; sxbr, sdbr, sebr, sxb, sdb, seb, sxtr, sdtr
  (define_insn "*sub<mode>3_cc"
    [(set (reg CC_REGNUM)
! 	(compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "<f0>,0")
! 			    (match_operand:FP 2 "general_operand"      "f,<Rf>"))
! 		 (match_operand:FP 3 "const0_operand" "")))
!    (set (match_operand:FP 0 "register_operand" "=f,f")
! 	(minus:FP (match_dup 1) (match_dup 2)))]
    "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
    "@
!    s<xde><bt>r\t%0,<op1>%2
     s<xde>b\t%0,%2"
!   [(set_attr "op_type"  "<RRer>,RXE")
!    (set_attr "type"     "fsimp<bfp>")])
  
! ; sxbr, sdbr, sebr, sxb, sdb, seb, sxtr, sdtr
  (define_insn "*sub<mode>3_cconly"
    [(set (reg CC_REGNUM)
! 	(compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" "<f0>,0")
! 			   (match_operand:FP 2 "general_operand"      "f,<Rf>"))
! 		 (match_operand:FP 3 "const0_operand" "")))
!    (clobber (match_scratch:FP 0 "=f,f"))]
    "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
    "@
!    s<xde><bt>r\t%0,<op1>%2
     s<xde>b\t%0,%2"
!   [(set_attr "op_type"  "<RRer>,RXE")
!    (set_attr "type"     "fsimp<bfp>")])
  
  ; sxr, sdr, ser, sx, sd, se
  (define_insn "*sub<mode>3_ibm"
***************
*** 4531,4557 ****
     (set_attr "type"     "imulsi")])
  
  ;
! ; mul(df|sf)3 instruction pattern(s).
  ;
  
  (define_expand "mul<mode>3"
!   [(set (match_operand:BFP 0 "register_operand" "=f,f")
!         (mult:BFP (match_operand:BFP 1 "nonimmediate_operand" "%0,0")
!                   (match_operand:BFP 2 "general_operand" "f,<Rf>")))]
    "TARGET_HARD_FLOAT"
    "")
  
! ; mxbr mdbr, meebr, mxb, mxb, meeb
  (define_insn "*mul<mode>3"
!   [(set (match_operand:BFP 0 "register_operand" "=f,f")
!         (mult:BFP (match_operand:BFP 1 "nonimmediate_operand" "%0,0")
!                   (match_operand:BFP 2 "general_operand" "f,<Rf>")))]
    "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
    "@
!    m<xdee>br\t%0,%2
     m<xdee>b\t%0,%2"
!   [(set_attr "op_type"  "RRE,RXE")
!    (set_attr "type"     "fmul<mode>")])
  
  ; mxr, mdr, mer, mx, md, me
  (define_insn "*mul<mode>3_ibm"
--- 4700,4726 ----
     (set_attr "type"     "imulsi")])
  
  ;
! ; mul(tf|df|sf|td|dd)3 instruction pattern(s).
  ;
  
  (define_expand "mul<mode>3"
!   [(set (match_operand:FP 0 "register_operand" "")
!         (mult:FP (match_operand:FP 1 "nonimmediate_operand" "")
!                   (match_operand:FP 2 "general_operand" "")))]
    "TARGET_HARD_FLOAT"
    "")
  
! ; mxbr mdbr, meebr, mxb, mxb, meeb, mdtr, mxtr
  (define_insn "*mul<mode>3"
!   [(set (match_operand:FP 0 "register_operand"              "=f,f")
!         (mult:FP (match_operand:FP 1 "nonimmediate_operand" "%<f0>,0")
!                  (match_operand:FP 2 "general_operand"      "f,<Rf>")))]
    "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
    "@
!    m<xdee><bt>r\t%0,<op1>%2
     m<xdee>b\t%0,%2"
!   [(set_attr "op_type"  "<RRer>,RXE")
!    (set_attr "type"     "fmul<bfp>")])
  
  ; mxr, mdr, mer, mx, md, me
  (define_insn "*mul<mode>3_ibm"
***************
*** 5014,5036 ****
  ;
  
  (define_expand "div<mode>3"
!   [(set (match_operand:BFP 0 "register_operand" "=f,f")
!         (div:BFP (match_operand:BFP 1 "register_operand" "0,0")
!                  (match_operand:BFP 2 "general_operand" "f,<Rf>")))]
    "TARGET_HARD_FLOAT"
    "")
  
! ; dxbr, ddbr, debr, dxb, ddb, deb
  (define_insn "*div<mode>3"
!   [(set (match_operand:BFP 0 "register_operand" "=f,f")
!         (div:BFP (match_operand:BFP 1 "register_operand" "0,0")
!                  (match_operand:BFP 2 "general_operand" "f,<Rf>")))]
    "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
    "@
!    d<xde>br\t%0,%2
     d<xde>b\t%0,%2"
!   [(set_attr "op_type"  "RRE,RXE")
!    (set_attr "type"     "fdiv<mode>")])
  
  ; dxr, ddr, der, dx, dd, de
  (define_insn "*div<mode>3_ibm"
--- 5183,5205 ----
  ;
  
  (define_expand "div<mode>3"
!   [(set (match_operand:FP 0 "register_operand" "")
!         (div:FP (match_operand:FP 1 "register_operand" "")
!                  (match_operand:FP 2 "general_operand" "")))]
    "TARGET_HARD_FLOAT"
    "")
  
! ; dxbr, ddbr, debr, dxb, ddb, deb, ddtr, dxtr
  (define_insn "*div<mode>3"
!   [(set (match_operand:FP 0 "register_operand"          "=f,f")
!         (div:FP (match_operand:FP 1 "register_operand" "<f0>,0")
!                  (match_operand:FP 2 "general_operand"  "f,<Rf>")))]
    "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT"
    "@
!    d<xde><bt>r\t%0,<op1>%2
     d<xde>b\t%0,%2"
!   [(set_attr "op_type"  "<RRer>,RXE")
!    (set_attr "type"     "fdiv<bfp>")])
  
  ; dxr, ddr, der, dx, dd, de
  (define_insn "*div<mode>3_ibm"
***************
*** 6045,6056 ****
  
  ; lcdfr
  (define_insn "*neg<mode>2_nocc"
!   [(set (match_operand:BFP 0 "register_operand"          "=f")
!         (neg:BFP (match_operand:BFP 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"
--- 6214,6225 ----
  
  ; lcdfr
  (define_insn "*neg<mode>2_nocc"
!   [(set (match_operand:FP 0 "register_operand"         "=f")
!         (neg:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
    "TARGET_HARD_FLOAT && TARGET_DFP"
    "lcdfr\t%0,%1"
    [(set_attr "op_type"  "RRE")
!    (set_attr "type"     "fsimp<bfp>")])
  
  ; lcxbr, lcdbr, lcebr
  (define_insn "*neg<mode>2"
***************
*** 6168,6179 ****
  
  ; lpdfr
  (define_insn "*abs<mode>2_nocc"
!   [(set (match_operand:BFP 0 "register_operand"          "=f")
!         (abs:BFP (match_operand:BFP 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"
--- 6337,6348 ----
  
  ; lpdfr
  (define_insn "*abs<mode>2_nocc"
!   [(set (match_operand:FP 0 "register_operand"         "=f")
!         (abs:FP (match_operand:FP 1 "register_operand" "<fT0>")))]
    "TARGET_HARD_FLOAT && TARGET_DFP"
    "lpdfr\t%0,%1"
    [(set_attr "op_type"  "RRE")
!    (set_attr "type"     "fsimp<bfp>")])
  
  ; lpxbr, lpdbr, lpebr
  (define_insn "*abs<mode>2"
***************
*** 6283,6294 ****
  
  ; lndfr
  (define_insn "*negabs<mode>2_nocc"
!   [(set (match_operand:BFP 0 "register_operand"                   "=f")
!         (neg:BFP (abs:BFP (match_operand:BFP 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"
--- 6452,6463 ----
  
  ; lndfr
  (define_insn "*negabs<mode>2_nocc"
!   [(set (match_operand:FP 0 "register_operand"                  "=f")
!         (neg:FP (abs:FP (match_operand:BFP 1 "register_operand" "<fT0>"))))]
    "TARGET_HARD_FLOAT && TARGET_DFP"
    "lndfr\t%0,%1"
    [(set_attr "op_type"  "RRE")
!    (set_attr "type"     "fsimp<bfp>")])
  
  ; lnxbr, lndbr, lnebr
  (define_insn "*negabs<mode>2"
***************
*** 6306,6319 ****
  
  ; cpsdr
  (define_insn "copysign<mode>3"
!   [(set (match_operand:BFP 0 "register_operand" "=f")
! 	(unspec:BFP [(match_operand:BFP 1 "register_operand" "<fT0>")
! 		     (match_operand:BFP 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.
--- 6475,6488 ----
  
  ; cpsdr
  (define_insn "copysign<mode>3"
!   [(set (match_operand:FP 0 "register_operand" "=f")
! 	(unspec:FP [(match_operand:FP 1 "register_operand" "<fT0>")
! 		    (match_operand:FP 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<bfp>")])
  
  ;;
  ;;- Square root instructions.



More information about the Gcc-patches mailing list