This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] S/390: DFP support 4/4: Add the DFP instruction support
- From: Andreas Krebbel <krebbel1 at de dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Ulrich dot Weigand at de dot ibm dot com
- Date: Fri, 16 Mar 2007 20:03:27 +0100
- Subject: [PATCH] S/390: DFP support 4/4: Add the DFP instruction support
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.