X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fconfig%2Fs390%2Fs390.md;h=fbabfdd2def2830a1c7199cdc2813031ec24ad1d;hb=5497187ba8461f8adfaebfea0f63aa46e94cdbe4;hp=274c2336edd3a5d883b56bcd300f2516c3658e9e;hpb=38d26fa60f652cbfa8b0a1d63ed4ee8230f5a30b;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 274c2336edd..fbabfdd2def 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -1,5 +1,5 @@ ;;- Machine description for GNU compiler -- S/390 / zSeries version. -;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 +;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 ;; Free Software Foundation, Inc. ;; Contributed by Hartmut Penner (hpenner@de.ibm.com) and ;; Ulrich Weigand (uweigand@de.ibm.com). @@ -8,7 +8,7 @@ ;; GCC is free software; you can redistribute it and/or modify it under ;; the terms of the GNU General Public License as published by the Free -;; Software Foundation; either version 2, or (at your option) any later +;; Software Foundation; either version 3, or (at your option) any later ;; version. ;; GCC is distributed in the hope that it will be useful, but WITHOUT ANY @@ -17,56 +17,13 @@ ;; for more details. ;; You should have received a copy of the GNU General Public License -;; along with GCC; see the file COPYING. If not, write to the Free -;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA -;; 02110-1301, USA. +;; along with GCC; see the file COPYING3. If not see +;; . ;; -;; Special constraints for s/390 machine description: -;; -;; a -- Any address register from 1 to 15. -;; c -- Condition code register 33. -;; d -- Any register from 0 to 15. -;; f -- Floating point registers. -;; t -- Access registers 36 and 37. -;; G -- Const double zero operand -;; I -- An 8-bit constant (0..255). -;; J -- A 12-bit constant (0..4095). -;; K -- A 16-bit constant (-32768..32767). -;; L -- Value appropriate as displacement. -;; (0..4095) for short displacement -;; (-524288..524287) for long displacement -;; M -- Constant integer with a value of 0x7fffffff. -;; N -- Multiple letter constraint followed by 4 parameter letters. -;; 0..9,x: number of the part counting from most to least significant -;; H,Q: mode of the part -;; D,S,H: mode of the containing operand -;; 0,F: value of the other parts (F - all bits set) -;; -;; The constraint matches if the specified part of a constant -;; has a value different from its other parts. If the letter x -;; is specified instead of a part number, the constraint matches -;; if there is any single part with non-default value. -;; O -- Multiple letter constraint followed by 1 parameter. -;; s: Signed extended immediate value (-2G .. 2G-1). -;; p: Positive extended immediate value (0 .. 4G-1). -;; n: Negative extended immediate value (-4G .. -1). -;; These constraints do not accept any operand if the machine does -;; not provide the extended-immediate facility. -;; P -- Any integer constant that can be loaded without literal pool. -;; Q -- Memory reference without index register and with short displacement. -;; R -- Memory reference with index register and short displacement. -;; S -- Memory reference without index register but with long displacement. -;; T -- Memory reference with index register and long displacement. -;; A -- Multiple letter constraint followed by Q, R, S, or T: -;; Offsettable memory reference of type specified by second letter. -;; B -- Multiple letter constraint followed by Q, R, S, or T: -;; Memory reference of the type specified by second letter that -;; does *not* refer to a literal pool entry. -;; U -- Pointer with short displacement. -;; W -- Pointer with long displacement. -;; Y -- Shift count operand. +;; See constraints.md for a description of constraints specific to s390. ;; + ;; Special formats used for outputting 390 instructions. ;; ;; %C: print opcode suffix for branch condition. @@ -101,7 +58,8 @@ (define_constants [; Miscellaneous (UNSPEC_ROUND 1) - (UNSPEC_CMPINT 2) + (UNSPEC_CCU_TO_INT 2) + (UNSPEC_CCZ_TO_INT 3) (UNSPEC_ICM 10) ; GOT/PLT and lt-relative accesses @@ -135,10 +93,16 @@ ; String Functions (UNSPEC_SRST 600) (UNSPEC_MVST 601) - + ; Stack Smashing Protector (UNSPEC_SP_SET 700) (UNSPEC_SP_TEST 701) + + ; Copy sign instructions + (UNSPEC_COPYSIGN 800) + + ; Test Data Class (TDC) + (UNSPEC_TDC_INSN 900) ]) ;; @@ -172,6 +136,8 @@ ;; Registers ;; +; Registers with special meaning + (define_constants [ ; Sibling call register. @@ -186,12 +152,43 @@ (TP_REGNUM 36) ]) +; Hardware register names + +(define_constants + [ + ; General purpose registers + (GPR0_REGNUM 0) + ; Floating point registers. + (FPR0_REGNUM 16) + (FPR2_REGNUM 18) + ]) + +;; +;; PFPO GPR0 argument format +;; + +(define_constants + [ + ; PFPO operation type + (PFPO_CONVERT 0x1000000) + ; PFPO operand types + (PFPO_OP_TYPE_SF 0x5) + (PFPO_OP_TYPE_DF 0x6) + (PFPO_OP_TYPE_TF 0x7) + (PFPO_OP_TYPE_SD 0x8) + (PFPO_OP_TYPE_DD 0x9) + (PFPO_OP_TYPE_TD 0xa) + ; Bitposition of operand types + (PFPO_OP0_TYPE_SHIFT 16) + (PFPO_OP1_TYPE_SHIFT 8) + ]) + ;; Instruction operand type as used in the Principles of Operation. ;; Used to determine defaults for length and other attribute values. (define_attr "op_type" - "NN,E,RR,RRE,RX,RS,RSI,RI,SI,S,SS,SSE,RXE,RSE,RIL,RIE,RXY,RSY,SIY" + "NN,E,RR,RRE,RX,RS,RSI,RI,SI,S,SS,SSE,RXE,RSE,RIL,RIE,RXY,RSY,SIY,RRF,RRR" (const_string "NN")) ;; Instruction type attribute used for scheduling. @@ -199,11 +196,11 @@ (define_attr "type" "none,integer,load,lr,la,larl,lm,stm, cs,vs,store,sem,idiv, imulhi,imulsi,imuldi, - branch,jsr,fsimpdf,fsimpsf, - floaddf,floadsf,fstoredf,fstoresf, - fmuldf,fmulsf,fdivdf,fdivsf, - ftoi,itof,fsqrtdf,fsqrtsf, - other" + branch,jsr,fsimptf,fsimpdf,fsimpsf, + floadtf,floaddf,floadsf,fstoredf,fstoresf, + fmultf,fmuldf,fmulsf,fdivtf,fdivdf,fdivsf, + ftoi,itof,fsqrttf,fsqrtdf,fsqrtsf, + ftrunctf,ftruncdf,other" (cond [(eq_attr "op_type" "NN") (const_string "other") (eq_attr "op_type" "SS") (const_string "cs")] (const_string "integer"))) @@ -237,67 +234,122 @@ ;; this description is also used for the g5 and g6. (include "2064.md") -;; Pipeline description for z990. +;; Pipeline description for z990, z9-109 and z9-ec. (include "2084.md") ;; Predicates (include "predicates.md") +;; Constraint definitions +(include "constraints.md") + ;; Other includes (include "tpf.md") -;; Macros +;; Iterators -;; This mode macro allows DF and SF patterns to be generated from the +;; These mode iterators allow floating point patterns to be generated from the ;; same template. -(define_mode_macro FPR [DF SF]) - -;; These mode macros allow 31-bit and 64-bit TDSI patterns to be generated +(define_mode_iterator FP [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")]) +(define_mode_iterator BFP [TF DF SF]) +(define_mode_iterator DFP [TD DD]) +(define_mode_iterator DFP_ALL [TD DD SD]) +(define_mode_iterator DSF [DF SF]) +(define_mode_iterator SD_SF [SF SD]) +(define_mode_iterator DD_DF [DF DD]) +(define_mode_iterator TD_TF [TF TD]) + +;; This mode iterator allows 31-bit and 64-bit TDSI patterns to be generated ;; from the same template. -(define_mode_macro TDSI [(TI "TARGET_64BIT") DI SI]) +(define_mode_iterator TDSI [(TI "TARGET_64BIT") DI SI]) -;; These mode macros allow 31-bit and 64-bit GPR patterns to be generated +;; These mode iterators allow 31-bit and 64-bit GPR patterns to be generated ;; from the same template. -(define_mode_macro GPR [(DI "TARGET_64BIT") SI]) -(define_mode_macro DSI [DI SI]) +(define_mode_iterator GPR [(DI "TARGET_64BIT") SI]) +(define_mode_iterator DSI [DI SI]) -;; This mode macro allows :P to be used for patterns that operate on +;; These mode iterators allow :P to be used for patterns that operate on ;; pointer-sized quantities. Exactly one of the two alternatives will match. -(define_mode_macro DP [(TI "TARGET_64BIT") (DI "!TARGET_64BIT")]) -(define_mode_macro P [(DI "TARGET_64BIT") (SI "!TARGET_64BIT")]) +(define_mode_iterator DP [(TI "TARGET_64BIT") (DI "!TARGET_64BIT")]) +(define_mode_iterator P [(DI "TARGET_64BIT") (SI "!TARGET_64BIT")]) -;; This mode macro allows the QI and HI patterns to be defined from +;; This mode iterator allows the QI and HI patterns to be defined from ;; the same template. -(define_mode_macro HQI [HI QI]) +(define_mode_iterator HQI [HI QI]) -;; This mode macro allows the integer patterns to be defined from the +;; This mode iterator allows the integer patterns to be defined from the ;; same template. -(define_mode_macro INT [(DI "TARGET_64BIT") SI HI QI]) +(define_mode_iterator INT [(DI "TARGET_64BIT") SI HI QI]) -;; This macro allows to unify all 'bCOND' expander patterns. -(define_code_macro COMPARE [eq ne gt gtu lt ltu ge geu le leu unordered +;; This iterator allows to unify all 'bCOND' expander patterns. +(define_code_iterator COMPARE [eq ne gt gtu lt ltu ge geu le leu unordered ordered uneq unlt ungt unle unge ltgt]) -;; This macro allows to unify all 'sCOND' patterns. -(define_code_macro SCOND [ltu gtu leu geu]) +;; This iterator allows to unify all 'sCOND' patterns. +(define_code_iterator SCOND [ltu gtu leu geu]) -;; This macro allows some 'ashift' and 'lshiftrt' pattern to be defined from +;; This iterator allows some 'ashift' and 'lshiftrt' pattern to be defined from ;; the same template. -(define_code_macro SHIFT [ashift lshiftrt]) +(define_code_iterator SHIFT [ashift lshiftrt]) -;; These macros allow to combine most atomic operations. -(define_code_macro ATOMIC [and ior xor plus minus mult]) +;; This iterator and attribute allow to combine most atomic operations. +(define_code_iterator ATOMIC [and ior xor plus minus mult]) (define_code_attr atomic [(and "and") (ior "ior") (xor "xor") (plus "add") (minus "sub") (mult "nand")]) +;; In FP templates, a string like "ltbr" 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 in "mr" will expand to "mxr" in +;; TF/TDmode, "mdr" in DF/DDmode, "meer" in SFmode and "mer in +;; SDmode. +(define_mode_attr xdee [(TF "x") (DF "d") (SF "ee") (TD "x") (DD "d") (SD "e")]) + +;; In FP templates, "" will expand to "RRE" in TFmode and "RR" otherwise. +;; Likewise for "". +(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 attributes allow to merge the bfp and +;; dfp variants in a single insn definition. -;; In FPR templates, a string like "ltbr" will expand to "ltdbr" in DFmode -;; and "ltebr" in SFmode. -(define_mode_attr de [(DF "d") (SF "e")]) +;; This attribute is used to set op_type accordingly. +(define_mode_attr RRer [(TF "RRE") (DF "RRE") (SF "RRE") (TD "RRR") + (DD "RRR") (SD "RRR")]) + +;; This attribute 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 attribute 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. +;; TFmode values are represented by a fp register pair. Since the +;; sign bit instructions only handle single source and target fp registers +;; these instructions can only be used for TFmode values if the source and +;; target operand uses the same fp register. +(define_mode_attr fT0 [(TF "0") (DF "f") (SF "f")]) + +;; In FP templates, "" 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 attribute 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 imprecise 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 FPR templates, a string like "mbr" will expand to "mdbr" in DFmode -;; and "meebr" in SFmode. This is needed for the 'mul3' pattern. -(define_mode_attr dee [(DF "d") (SF "ee")]) ;; In GPR and P templates, a constraint like "" will expand to "d" in DImode ;; and "0" in SImode. This allows to combine instructions of which the 31bit @@ -321,6 +373,10 @@ ;; in "RRE" for DImode and "RR" for SImode. (define_mode_attr E [(DI "E") (SI "")]) +;; This attribute handles differences in the instruction 'type' and makes RX +;; to result in "RXY" for DImode and "RX" for SImode. +(define_mode_attr Y [(DI "Y") (SI "")]) + ;; This attribute handles differences in the instruction 'type' and will result ;; in "RSE" for TImode and "RS" for DImode. (define_mode_attr TE [(TI "E") (DI "")]) @@ -329,6 +385,12 @@ ;; and "lcr" in SImode. (define_mode_attr g [(DI "g") (SI "")]) +;; In GPR templates, a string like "sl" will expand to "slg" in DImode +;; and "sly" in SImode. This is useful because on 64bit the ..g instructions +;; were enhanced with long displacements whereas 31bit instructions got a ..y +;; variant for long displacements. +(define_mode_attr y [(DI "g") (SI "y")]) + ;; In DP templates, a string like "cds" will expand to "cdsg" in TImode ;; and "cds" in DImode. (define_mode_attr tg [(TI "g") (DI "")]) @@ -349,6 +411,10 @@ ;; 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")]) @@ -370,8 +436,8 @@ (define_expand "cmp" [(set (reg:CC CC_REGNUM) - (compare:CC (match_operand:FPR 0 "register_operand" "") - (match_operand:FPR 1 "general_operand" "")))] + (compare:CC (match_operand:FP 0 "register_operand" "") + (match_operand:FP 1 "general_operand" "")))] "TARGET_HARD_FLOAT" { s390_compare_op0 = operands[0]; @@ -430,7 +496,11 @@ [(set_attr "op_type" "RI")]) +; ; Load-and-Test instructions +; + +; tst(di|si) instruction pattern(s). (define_insn "*tstdi_sign" [(set (reg CC_REGNUM) @@ -443,28 +513,30 @@ "ltgfr\t%2,%0" [(set_attr "op_type" "RRE")]) -(define_insn "*tstdi_extimm" +; ltr, lt, ltgr, ltg +(define_insn "*tst_extimm" [(set (reg CC_REGNUM) - (compare (match_operand:DI 0 "nonimmediate_operand" "d,m") - (match_operand:DI 1 "const0_operand" ""))) - (set (match_operand:DI 2 "register_operand" "=d,d") + (compare (match_operand:GPR 0 "nonimmediate_operand" "d,m") + (match_operand:GPR 1 "const0_operand" ""))) + (set (match_operand:GPR 2 "register_operand" "=d,d") (match_dup 0))] - "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT && TARGET_EXTIMM" + "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM" "@ - ltgr\t%2,%0 - ltg\t%2,%0" - [(set_attr "op_type" "RRE,RXY")]) + ltr\t%2,%0 + lt\t%2,%0" + [(set_attr "op_type" "RR,RXY")]) -(define_insn "*tstdi_cconly_extimm" +; ltr, lt, ltgr, ltg +(define_insn "*tst_cconly_extimm" [(set (reg CC_REGNUM) - (compare (match_operand:DI 0 "nonimmediate_operand" "d,m") - (match_operand:DI 1 "const0_operand" ""))) - (clobber (match_scratch:DI 2 "=X,d"))] - "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT && TARGET_EXTIMM" + (compare (match_operand:GPR 0 "nonimmediate_operand" "d,m") + (match_operand:GPR 1 "const0_operand" ""))) + (clobber (match_scratch:GPR 2 "=X,d"))] + "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM" "@ - ltgr\t%0,%0 - ltg\t%2,%0" - [(set_attr "op_type" "RRE,RXY")]) + ltr\t%0,%0 + lt\t%2,%0" + [(set_attr "op_type" "RR,RXY")]) (define_insn "*tstdi" [(set (reg CC_REGNUM) @@ -476,46 +548,6 @@ "ltgr\t%2,%0" [(set_attr "op_type" "RRE")]) -(define_insn "*tstdi_cconly" - [(set (reg CC_REGNUM) - (compare (match_operand:DI 0 "register_operand" "d") - (match_operand:DI 1 "const0_operand" "")))] - "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT" - "ltgr\t%0,%0" - [(set_attr "op_type" "RRE")]) - -(define_insn "*tstdi_cconly_31" - [(set (reg CC_REGNUM) - (compare (match_operand:DI 0 "register_operand" "d") - (match_operand:DI 1 "const0_operand" "")))] - "s390_match_ccmode(insn, CCSmode) && !TARGET_64BIT" - "srda\t%0,0" - [(set_attr "op_type" "RS") - (set_attr "atype" "reg")]) - -(define_insn "*tstsi_extimm" - [(set (reg CC_REGNUM) - (compare (match_operand:SI 0 "nonimmediate_operand" "d,m") - (match_operand:SI 1 "const0_operand" ""))) - (set (match_operand:SI 2 "register_operand" "=d,d") - (match_dup 0))] - "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM" - "@ - ltr\t%2,%0 - lt\t%2,%0" - [(set_attr "op_type" "RR,RXY")]) - -(define_insn "*tstsi_cconly_extimm" - [(set (reg CC_REGNUM) - (compare (match_operand:SI 0 "nonimmediate_operand" "d,m") - (match_operand:SI 1 "const0_operand" ""))) - (clobber (match_scratch:SI 2 "=X,d"))] - "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM" - "@ - ltr\t%0,%0 - lt\t%2,%0" - [(set_attr "op_type" "RR,RXY")]) - (define_insn "*tstsi" [(set (reg CC_REGNUM) (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S") @@ -541,13 +573,25 @@ icmy\t%2,15,%S0" [(set_attr "op_type" "RR,RS,RSY")]) -(define_insn "*tstsi_cconly2" +(define_insn "*tstdi_cconly_31" + [(set (reg CC_REGNUM) + (compare (match_operand:DI 0 "register_operand" "d") + (match_operand:DI 1 "const0_operand" "")))] + "s390_match_ccmode(insn, CCSmode) && !TARGET_64BIT" + "srda\t%0,0" + [(set_attr "op_type" "RS") + (set_attr "atype" "reg")]) + +; ltr, ltgr +(define_insn "*tst_cconly2" [(set (reg CC_REGNUM) - (compare (match_operand:SI 0 "register_operand" "d") - (match_operand:SI 1 "const0_operand" "")))] + (compare (match_operand:GPR 0 "register_operand" "d") + (match_operand:GPR 1 "const0_operand" "")))] "s390_match_ccmode(insn, CCSmode)" - "ltr\t%0,%0" - [(set_attr "op_type" "RR")]) + "ltr\t%0,%0" + [(set_attr "op_type" "RR")]) + +; tst(hi|qi) instruction pattern(s). (define_insn "*tstCCT" [(set (reg CC_REGNUM) @@ -651,18 +695,6 @@ cgf\t%0,%1" [(set_attr "op_type" "RRE,RXY")]) -(define_insn "*cmpdi_ccs" - [(set (reg CC_REGNUM) - (compare (match_operand:DI 0 "register_operand" "d,d,d,d") - (match_operand:DI 1 "general_operand" "d,K,Os,m")))] - "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT" - "@ - cgr\t%0,%1 - cghi\t%0,%h1 - cgfi\t%0,%1 - cg\t%0,%1" - [(set_attr "op_type" "RRE,RI,RIL,RXY")]) - (define_insn "*cmpsi_ccs_sign" [(set (reg CC_REGNUM) (compare (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T")) @@ -673,18 +705,19 @@ chy\t%0,%1" [(set_attr "op_type" "RX,RXY")]) -(define_insn "*cmpsi_ccs" +; cr, chi, cfi, c, cy, cgr, cghi, cgfi, cg +(define_insn "*cmp_ccs" [(set (reg CC_REGNUM) - (compare (match_operand:SI 0 "register_operand" "d,d,d,d,d") - (match_operand:SI 1 "general_operand" "d,K,Os,R,T")))] + (compare (match_operand:GPR 0 "register_operand" "d,d,d,d,d") + (match_operand:GPR 1 "general_operand" "d,K,Os,R,T")))] "s390_match_ccmode(insn, CCSmode)" "@ - cr\t%0,%1 - chi\t%0,%h1 - cfi\t%0,%1 - c\t%0,%1 - cy\t%0,%1" - [(set_attr "op_type" "RR,RI,RIL,RX,RXY")]) + cr\t%0,%1 + chi\t%0,%h1 + cfi\t%0,%1 + c\t%0,%1 + c\t%0,%1" + [(set_attr "op_type" "RR,RI,RIL,RX,RXY")]) ; Compare (unsigned) instructions @@ -789,48 +822,29 @@ }) -; (DF|SF) instructions +; (TF|DF|SF|TD|DD|SD) instructions +; ltxbr, ltdbr, ltebr, ltxtr, ltdtr (define_insn "*cmp_ccs_0" [(set (reg CC_REGNUM) - (compare (match_operand:FPR 0 "register_operand" "f") - (match_operand:FPR 1 "const0_operand" "")))] - "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "ltbr\t%0,%0" + (compare (match_operand:FP 0 "register_operand" "f") + (match_operand:FP 1 "const0_operand" "")))] + "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT" + "ltr\t%0,%0" [(set_attr "op_type" "RRE") - (set_attr "type" "fsimp")]) - -(define_insn "*cmp_ccs_0_ibm" - [(set (reg CC_REGNUM) - (compare (match_operand:FPR 0 "register_operand" "f") - (match_operand:FPR 1 "const0_operand" "")))] - "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" - "ltr\t%0,%0" - [(set_attr "op_type" "RR") - (set_attr "type" "fsimp")]) + (set_attr "type" "fsimp")]) +; cxtr, cxbr, cdbr, cebr, cxb, cdb, ceb, cxbtr, cdbtr (define_insn "*cmp_ccs" [(set (reg CC_REGNUM) - (compare (match_operand:FPR 0 "register_operand" "f,f") - (match_operand:FPR 1 "general_operand" "f,R")))] - "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" + (compare (match_operand:FP 0 "register_operand" "f,f") + (match_operand:FP 1 "general_operand" "f,")))] + "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT" "@ - cbr\t%0,%1 - cb\t%0,%1" + cr\t%0,%1 + cb\t%0,%1" [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fsimp")]) - -(define_insn "*cmp_ccs_ibm" - [(set (reg CC_REGNUM) - (compare (match_operand:FPR 0 "register_operand" "f,f") - (match_operand:FPR 1 "general_operand" "f,R")))] - "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" - "@ - cr\t%0,%1 - c\t%0,%1" - [(set_attr "op_type" "RR,RX") - (set_attr "type" "fsimp")]) - + (set_attr "type" "fsimp")]) ;; ;;- Move instructions. @@ -893,11 +907,43 @@ operands[1] = replace_equiv_address (operands[1], addr); }) -(define_expand "reload_outti" - [(parallel [(match_operand:TI 0 "" "") - (match_operand:TI 1 "register_operand" "d") - (match_operand:DI 2 "register_operand" "=&a")])] - "TARGET_64BIT" + +; +; Patterns used for secondary reloads +; + +; Handles loading a PLUS (load address) expression + +(define_expand "reload_plus" + [(parallel [(match_operand:P 0 "register_operand" "=a") + (match_operand:P 1 "s390_plus_operand" "") + (match_operand:P 2 "register_operand" "=&a")])] + "" +{ + s390_expand_plus_operand (operands[0], operands[1], operands[2]); + DONE; +}) + +; Handles assessing a non-offsetable memory address + +(define_expand "reload_nonoffmem_in" + [(parallel [(match_operand 0 "register_operand" "") + (match_operand 1 "" "") + (match_operand:P 2 "register_operand" "=&a")])] + "" +{ + gcc_assert (MEM_P (operands[1])); + s390_load_address (operands[2], find_replacement (&XEXP (operands[1], 0))); + operands[1] = replace_equiv_address (operands[1], operands[2]); + emit_move_insn (operands[0], operands[1]); + DONE; +}) + +(define_expand "reload_nonoffmem_out" + [(parallel [(match_operand 0 "" "") + (match_operand 1 "register_operand" "") + (match_operand:P 2 "register_operand" "=&a")])] + "" { gcc_assert (MEM_P (operands[0])); s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0))); @@ -916,7 +962,11 @@ "" { /* Handle symbolic constants. */ - if (TARGET_64BIT && SYMBOLIC_CONST (operands[1])) + if (TARGET_64BIT + && (SYMBOLIC_CONST (operands[1]) + || (GET_CODE (operands[1]) == PLUS + && XEXP (operands[1], 0) == pic_offset_table_rtx + && SYMBOLIC_CONST (XEXP (operands[1], 1))))) emit_symbolic_move (operands); }) @@ -929,6 +979,44 @@ [(set_attr "op_type" "RIL") (set_attr "type" "larl")]) +(define_insn "*movdi_64dfp" + [(set (match_operand:DI 0 "nonimmediate_operand" + "=d,d,d,d,d,d,d,d,f,d,d,d,d, + m,!*f,!*f,!*f,!R,!T,d,t,Q,t,?Q") + (match_operand:DI 1 "general_operand" + "K,N0HD0,N1HD0,N2HD0,N3HD0,Os,N0SD0,N1SD0,d,f,L,d,m, + d,*f,R,T,*f,*f,t,d,t,Q,?Q"))] + "TARGET_64BIT && TARGET_DFP" + "@ + lghi\t%0,%h1 + llihh\t%0,%i1 + llihl\t%0,%i1 + llilh\t%0,%i1 + llill\t%0,%i1 + lgfi\t%0,%1 + llihf\t%0,%k1 + llilf\t%0,%k1 + ldgr\t%0,%1 + lgdr\t%0,%1 + lay\t%0,%a1 + lgr\t%0,%1 + lg\t%0,%1 + stg\t%1,%0 + ldr\t%0,%1 + ld\t%0,%1 + ldy\t%0,%1 + std\t%1,%0 + stdy\t%1,%0 + # + # + stam\t%1,%N1,%S0 + lam\t%0,%N0,%S1 + #" + [(set_attr "op_type" "RI,RI,RI,RI,RI,RIL,RIL,RIL,RRE,RRE,RXY,RRE,RXY,RXY, + RR,RX,RXY,RX,RXY,*,*,RS,RS,SS") + (set_attr "type" "*,*,*,*,*,*,*,*,floaddf,floaddf,la,lr,load,store, + floaddf,floaddf,floaddf,fstoredf,fstoredf,*,*,*,*,*")]) + (define_insn "*movdi_64extimm" [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,d,d,d,m,!*f,!*f,!*f,!R,!T,d,t,Q,t,?Q") @@ -1088,19 +1176,6 @@ operands[1] = replace_equiv_address (operands[1], addr); }) -(define_expand "reload_outdi" - [(parallel [(match_operand:DI 0 "" "") - (match_operand:DI 1 "register_operand" "d") - (match_operand:SI 2 "register_operand" "=&a")])] - "!TARGET_64BIT" -{ - gcc_assert (MEM_P (operands[0])); - s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0))); - operands[0] = replace_equiv_address (operands[0], operands[2]); - emit_move_insn (operands[0], operands[1]); - DONE; -}) - (define_peephole2 [(set (match_operand:DI 0 "register_operand" "") (mem:DI (match_operand 1 "address_operand" "")))] @@ -1147,16 +1222,6 @@ [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))] "") -(define_expand "reload_indi" - [(parallel [(match_operand:DI 0 "register_operand" "=a") - (match_operand:DI 1 "s390_plus_operand" "") - (match_operand:DI 2 "register_operand" "=&a")])] - "TARGET_64BIT" -{ - s390_expand_plus_operand (operands[0], operands[1], operands[2]); - DONE; -}) - ; ; movsi instruction pattern(s). ; @@ -1167,7 +1232,11 @@ "" { /* Handle symbolic constants. */ - if (!TARGET_64BIT && SYMBOLIC_CONST (operands[1])) + if (!TARGET_64BIT + && (SYMBOLIC_CONST (operands[1]) + || (GET_CODE (operands[1]) == PLUS + && XEXP (operands[1], 0) == pic_offset_table_rtx + && SYMBOLIC_CONST (XEXP(operands[1], 1))))) emit_symbolic_move (operands); }) @@ -1313,16 +1382,6 @@ [(set_attr "op_type" "RX") (set_attr "type" "la")]) -(define_expand "reload_insi" - [(parallel [(match_operand:SI 0 "register_operand" "=a") - (match_operand:SI 1 "s390_plus_operand" "") - (match_operand:SI 2 "register_operand" "=&a")])] - "!TARGET_64BIT" -{ - s390_expand_plus_operand (operands[0], operands[1], operands[2]); - DONE; -}) - ; ; movhi instruction pattern(s). ; @@ -1334,7 +1393,7 @@ { /* Make it explicit that loading a register from memory always sign-extends (at least) to SImode. */ - if (optimize && !no_new_pseudos + if (optimize && can_create_pseudo_p () && register_operand (operands[0], VOIDmode) && GET_CODE (operands[1]) == MEM) { @@ -1381,7 +1440,7 @@ { /* On z/Architecture, zero-extending from memory to register is just as fast as a QImode load. */ - if (TARGET_ZARCH && optimize && !no_new_pseudos + if (TARGET_ZARCH && optimize && can_create_pseudo_p () && register_operand (operands[0], VOIDmode) && GET_CODE (operands[1]) == MEM) { @@ -1463,18 +1522,158 @@ (set_attr "type" "lr,load,load,*")]) ; -; movdf instruction pattern(s). +; mov(tf|td) instruction pattern(s). +; + +(define_expand "mov" + [(set (match_operand:TD_TF 0 "nonimmediate_operand" "") + (match_operand:TD_TF 1 "general_operand" ""))] + "" + "") + +(define_insn "*mov_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 + lxr\t%0,%1 + # + # + lmg\t%0,%N0,%S1 + stmg\t%1,%N1,%S0 + # + # + #" + [(set_attr "op_type" "RRE,RRE,*,*,RSY,RSY,*,*,*") + (set_attr "type" "fsimptf,fsimptf,*,*,lm,stm,*,*,*")]) + +(define_insn "*mov_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 + lxr\t%0,%1 + # + # + #" + [(set_attr "op_type" "RRE,RRE,*,*,*") + (set_attr "type" "fsimptf,fsimptf,*,*,*")]) + +; 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, 0)" + [(set (match_dup 2) (match_dup 4)) + (set (match_dup 3) (match_dup 5))] +{ + operands[2] = operand_subword (operands[0], 0, 0, mode); + operands[3] = operand_subword (operands[0], 1, 0, mode); + operands[4] = operand_subword (operands[1], 0, 0, mode); + operands[5] = operand_subword (operands[1], 1, 0, 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, 1)" + [(set (match_dup 2) (match_dup 4)) + (set (match_dup 3) (match_dup 5))] +{ + operands[2] = operand_subword (operands[0], 1, 0, mode); + operands[3] = operand_subword (operands[0], 0, 0, mode); + operands[4] = operand_subword (operands[1], 1, 0, mode); + operands[5] = operand_subword (operands[1], 0, 0, 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); + s390_load_address (addr, XEXP (operands[1], 0)); + operands[1] = replace_equiv_address (operands[1], addr); +}) + +; 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 (mode, operands[0], + mode, 0); + operands[3] = simplify_gen_subreg (mode, operands[0], + mode, 8); + operands[4] = adjust_address_nv (operands[1], mode, 0); + operands[5] = adjust_address_nv (operands[1], 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], mode, 0); + operands[3] = adjust_address_nv (operands[0], mode, 8); + operands[4] = simplify_gen_subreg (mode, operands[1], + mode, 0); + operands[5] = simplify_gen_subreg (mode, operands[1], + mode, 8); +}) + +; +; mov(df|dd) instruction pattern(s). ; -(define_expand "movdf" - [(set (match_operand:DF 0 "nonimmediate_operand" "") - (match_operand:DF 1 "general_operand" ""))] +(define_expand "mov" + [(set (match_operand:DD_DF 0 "nonimmediate_operand" "") + (match_operand:DD_DF 1 "general_operand" ""))] "" "") -(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"))] +(define_insn "*mov_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 + ldr\t%0,%1 + ldgr\t%0,%1 + lgdr\t%0,%1 + ld\t%0,%1 + ldy\t%0,%1 + std\t%1,%0 + stdy\t%1,%0 + lgr\t%0,%1 + lg\t%0,%1 + stg\t%1,%0 + #" + [(set_attr "op_type" "RRE,RR,RRE,RRE,RX,RXY,RX,RXY,RRE,RXY,RXY,SS") + (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,floaddf,floaddf, + fstoredf,fstoredf,lr,load,store,*")]) + +(define_insn "*mov_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 @@ -1488,11 +1687,14 @@ 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"))] + (set_attr "type" "fsimp,fload,fload,fload, + fstore,fstore,lr,load,store,*")]) + +(define_insn "*mov_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 @@ -1509,70 +1711,59 @@ # #" [(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,*,*,*")]) + (set_attr "type" "fsimp,fload,fload,fload, + fstore,fstore,lm,lm,stm,stm,*,*,*")]) (define_split - [(set (match_operand:DF 0 "nonimmediate_operand" "") - (match_operand:DF 1 "general_operand" ""))] + [(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], DFmode, 0)" + && s390_split_ok_p (operands[0], operands[1], mode, 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); + operands[2] = operand_subword (operands[0], 0, 0, mode); + operands[3] = operand_subword (operands[0], 1, 0, mode); + operands[4] = operand_subword (operands[1], 0, 0, mode); + operands[5] = operand_subword (operands[1], 1, 0, mode); }) (define_split - [(set (match_operand:DF 0 "nonimmediate_operand" "") - (match_operand:DF 1 "general_operand" ""))] + [(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], DFmode, 1)" + && s390_split_ok_p (operands[0], operands[1], mode, 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); + operands[2] = operand_subword (operands[0], 1, 0, mode); + operands[3] = operand_subword (operands[0], 0, 0, mode); + operands[4] = operand_subword (operands[1], 1, 0, mode); + operands[5] = operand_subword (operands[1], 0, 0, mode); }) (define_split - [(set (match_operand:DF 0 "register_operand" "") - (match_operand:DF 1 "memory_operand" ""))] + [(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, DFmode); + rtx addr = operand_subword (operands[0], 1, 0, mode); 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])); - s390_load_address (operands[2], find_replacement (&XEXP (operands[0], 0))); - operands[0] = replace_equiv_address (operands[0], operands[2]); - emit_move_insn (operands[0], operands[1]); - DONE; -}) - ; -; movsf instruction pattern(s). +; mov(sf|sd) 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"))] +(define_insn "mov" + [(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 @@ -1588,8 +1779,8 @@ 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,*")]) + (set_attr "type" "fsimp,fload,fload,fload, + fstore,fstore,lr,load,load,store,store,*")]) ; ; movcc instruction pattern @@ -1695,7 +1886,7 @@ FAIL; operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count)); - if (no_new_pseudos) + if (!can_create_pseudo_p ()) { if (GET_CODE (XEXP (operands[1], 0)) == REG) { @@ -1785,7 +1976,7 @@ operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count)); - if (no_new_pseudos) + if (!can_create_pseudo_p ()) { if (GET_CODE (XEXP (operands[0], 0)) == REG) { @@ -1913,7 +2104,7 @@ (use (reg:SI 0))]) (parallel [(set (match_operand:SI 0 "register_operand" "=d") - (unspec:SI [(reg:CCU CC_REGNUM)] UNSPEC_CMPINT)) + (unspec:SI [(reg:CCU CC_REGNUM)] UNSPEC_CCU_TO_INT)) (clobber (reg:CC CC_REGNUM))])] "" { @@ -2111,6 +2302,59 @@ [(set_attr "length" "8") (set_attr "type" "vs")]) + +; +; Test data class. +; + +(define_expand "signbit2" + [(set (reg:CCZ CC_REGNUM) + (unspec:CCZ [(match_operand:BFP 1 "register_operand" "f") + (match_dup 2)] + UNSPEC_TDC_INSN)) + (set (match_operand:SI 0 "register_operand" "=d") + (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CCZ_TO_INT))] + "TARGET_HARD_FLOAT" +{ + operands[2] = GEN_INT (S390_TDC_SIGNBIT_SET); +}) + +(define_expand "isinf2" + [(set (reg:CCZ CC_REGNUM) + (unspec:CCZ [(match_operand:BFP 1 "register_operand" "f") + (match_dup 2)] + UNSPEC_TDC_INSN)) + (set (match_operand:SI 0 "register_operand" "=d") + (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CCZ_TO_INT))] + "TARGET_HARD_FLOAT" +{ + operands[2] = GEN_INT (S390_TDC_INFINITY); +}) + +; This insn is used to generate all variants of the Test Data Class +; instruction, namely tcxb, tcdb, and tceb. The insn's first operand +; is the register to be tested and the second one is the bit mask +; specifying the required test(s). +; +(define_insn "*TDC_insn_" + [(set (reg:CCZ CC_REGNUM) + (unspec:CCZ [(match_operand:BFP 0 "register_operand" "f") + (match_operand:SI 1 "const_int_operand")] UNSPEC_TDC_INSN))] + "TARGET_HARD_FLOAT" + "tcb\t%0,%1" + [(set_attr "op_type" "RXE") + (set_attr "type" "fsimp")]) + +(define_insn_and_split "*ccz_to_int" + [(set (match_operand:SI 0 "register_operand" "=d") + (unspec:SI [(match_operand:CCZ 1 "register_operand" "0")] + UNSPEC_CCZ_TO_INT))] + "" + "#" + "reload_completed" + [(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 28)))]) + + ; ; setmemM instruction pattern(s). ; @@ -2387,7 +2631,7 @@ (define_insn_and_split "cmpint" [(set (match_operand:SI 0 "register_operand" "=d") (unspec:SI [(match_operand:CCU 1 "register_operand" "0")] - UNSPEC_CMPINT)) + UNSPEC_CCU_TO_INT)) (clobber (reg:CC CC_REGNUM))] "" "#" @@ -2400,10 +2644,10 @@ (define_insn_and_split "*cmpint_cc" [(set (reg CC_REGNUM) (compare (unspec:SI [(match_operand:CCU 1 "register_operand" "0")] - UNSPEC_CMPINT) + UNSPEC_CCU_TO_INT) (const_int 0))) (set (match_operand:SI 0 "register_operand" "=d") - (unspec:SI [(match_dup 1)] UNSPEC_CMPINT))] + (unspec:SI [(match_dup 1)] UNSPEC_CCU_TO_INT))] "s390_match_ccmode (insn, CCSmode)" "#" "&& reload_completed" @@ -2420,7 +2664,7 @@ (define_insn_and_split "*cmpint_sign" [(set (match_operand:DI 0 "register_operand" "=d") (sign_extend:DI (unspec:SI [(match_operand:CCU 1 "register_operand" "0")] - UNSPEC_CMPINT))) + UNSPEC_CCU_TO_INT))) (clobber (reg:CC CC_REGNUM))] "TARGET_64BIT" "#" @@ -2434,11 +2678,11 @@ [(set (reg CC_REGNUM) (compare (ashiftrt:DI (ashift:DI (subreg:DI (unspec:SI [(match_operand:CCU 1 "register_operand" "0")] - UNSPEC_CMPINT) 0) + UNSPEC_CCU_TO_INT) 0) (const_int 32)) (const_int 32)) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=d") - (sign_extend:DI (unspec:SI [(match_dup 1)] UNSPEC_CMPINT)))] + (sign_extend:DI (unspec:SI [(match_dup 1)] UNSPEC_CCU_TO_INT)))] "s390_match_ccmode (insn, CCSmode) && TARGET_64BIT" "#" "&& reload_completed" @@ -2734,6 +2978,7 @@ ; extendqi(si|di)2 instruction pattern(s). ; +; lbr, lgbr, lb, lgb (define_insn "*extendqi2_extimm" [(set (match_operand:GPR 0 "register_operand" "=d,d") (sign_extend:GPR (match_operand:QI 1 "nonimmediate_operand" "d,m")))] @@ -2743,6 +2988,7 @@ lb\t%0,%1" [(set_attr "op_type" "RRE,RXY")]) +; lb, lgb (define_insn "*extendqi2" [(set (match_operand:GPR 0 "register_operand" "=d") (sign_extend:GPR (match_operand:QI 1 "memory_operand" "m")))] @@ -2771,11 +3017,6 @@ }) ; -; extendqihi2 instruction pattern(s). -; - - -; ; zero_extendsidi2 instruction pattern(s). ; @@ -2899,6 +3140,7 @@ } }) +; llhr, llcr, llghr, llgcr, llh, llc, llgh, llgc (define_insn "*zero_extend2_extimm" [(set (match_operand:GPR 0 "register_operand" "=d,d") (zero_extend:GPR (match_operand:HQI 1 "nonimmediate_operand" "d,m")))] @@ -2908,6 +3150,7 @@ ll\t%0,%1" [(set_attr "op_type" "RRE,RXY")]) +; llgh, llgc (define_insn "*zero_extend2" [(set (match_operand:GPR 0 "register_operand" "=d") (zero_extend:GPR (match_operand:HQI 1 "memory_operand" "m")))] @@ -2969,281 +3212,398 @@ (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_dfp (operands[0], temp, GEN_INT (11))); + emit_jump (label2); + + emit_label (label1); + emit_insn (gen_fix_truncdddi2_dfp (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_dfp (operands[0], temp, GEN_INT (11))); + emit_jump (label2); + + emit_label (label1); + emit_insn (gen_fix_trunctddi2_dfp (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). +; fixuns_trunc(sf|df)(si|di)2 and fix_trunc(sf|df)(si|di)2 +; instruction pattern(s). ; -(define_expand "fixuns_trunc2" +(define_expand "fixuns_trunc2" [(set (match_operand:GPR 0 "register_operand" "") - (unsigned_fix:GPR (match_operand:FPR 1 "register_operand" "")))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" + (unsigned_fix:GPR (match_operand:BFP 1 "register_operand" "")))] + "TARGET_HARD_FLOAT" { rtx label1 = gen_label_rtx (); rtx label2 = gen_label_rtx (); - rtx temp = gen_reg_rtx (mode); + rtx temp = gen_reg_rtx (mode); REAL_VALUE_TYPE cmp, sub; - operands[1] = force_reg (mode, operands[1]); - real_2expN (&cmp, GET_MODE_BITSIZE(mode) - 1); - real_2expN (&sub, GET_MODE_BITSIZE(mode)); + operands[1] = force_reg (mode, operands[1]); + real_2expN (&cmp, GET_MODE_BITSIZE(mode) - 1, mode); + real_2expN (&sub, GET_MODE_BITSIZE(mode), mode); - emit_insn (gen_cmp (operands[1], - CONST_DOUBLE_FROM_REAL_VALUE (cmp, mode))); + emit_insn (gen_cmp (operands[1], + CONST_DOUBLE_FROM_REAL_VALUE (cmp, mode))); emit_jump_insn (gen_blt (label1)); - emit_insn (gen_sub3 (temp, operands[1], - CONST_DOUBLE_FROM_REAL_VALUE (sub, mode))); - emit_insn (gen_fix_trunc2_ieee (operands[0], temp, - GEN_INT(7))); + emit_insn (gen_sub3 (temp, operands[1], + CONST_DOUBLE_FROM_REAL_VALUE (sub, mode))); + emit_insn (gen_fix_trunc2_bfp (operands[0], temp, + GEN_INT (7))); emit_jump (label2); emit_label (label1); - emit_insn (gen_fix_trunc2_ieee (operands[0], - operands[1], GEN_INT(5))); + emit_insn (gen_fix_trunc2_bfp (operands[0], + operands[1], GEN_INT (5))); emit_label (label2); DONE; }) -(define_expand "fix_truncdi2" - [(set (match_operand:DI 0 "register_operand" "") - (fix:DI (match_operand:FPR 1 "nonimmediate_operand" "")))] - "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" +(define_expand "fix_trunc2" + [(set (match_operand:GPR 0 "register_operand" "") + (fix:GPR (match_operand:DSF 1 "register_operand" "")))] + "TARGET_HARD_FLOAT" { - operands[1] = force_reg (mode, operands[1]); - emit_insn (gen_fix_truncdi2_ieee (operands[0], operands[1], - GEN_INT(5))); + emit_insn (gen_fix_trunc2_bfp (operands[0], operands[1], + GEN_INT (5))); DONE; }) -(define_insn "fix_trunc2_ieee" +; cgxbr, cgdbr, cgebr, cfxbr, cfdbr, cfebr +(define_insn "fix_trunc2_bfp" [(set (match_operand:GPR 0 "register_operand" "=d") - (fix:GPR (match_operand:FPR 1 "register_operand" "f"))) + (fix:GPR (match_operand:BFP 1 "register_operand" "f"))) (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND) (clobber (reg:CC CC_REGNUM))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "cbr\t%0,%h2,%1" + "TARGET_HARD_FLOAT" + "cbr\t%0,%h2,%1" [(set_attr "op_type" "RRE") (set_attr "type" "ftoi")]) + ; -; fix_truncdfsi2 instruction pattern(s). +; fix_trunc(td|dd)di2 instruction pattern(s). ; -(define_expand "fix_truncdfsi2" - [(set (match_operand:SI 0 "register_operand" "") - (fix:SI (match_operand:DF 1 "nonimmediate_operand" "")))] - "TARGET_HARD_FLOAT" +(define_expand "fix_truncdi2" + [(set (match_operand:DI 0 "register_operand" "") + (fix:DI (match_operand:DFP 1 "nonimmediate_operand" "")))] + "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_HARD_DFP" { - if (TARGET_IBM_FLOAT) - { - /* This is the algorithm from POP chapter A.5.7.2. */ - - rtx temp = assign_stack_local (BLKmode, 8, BITS_PER_WORD); - rtx two31r = s390_gen_rtx_const_DI (0x4f000000, 0x08000000); - rtx two32 = s390_gen_rtx_const_DI (0x4e000001, 0x00000000); - - operands[1] = force_reg (DFmode, operands[1]); - emit_insn (gen_fix_truncdfsi2_ibm (operands[0], operands[1], - two31r, two32, temp)); - } - else - { - operands[1] = force_reg (DFmode, operands[1]); - emit_insn (gen_fix_truncdfsi2_ieee (operands[0], operands[1], GEN_INT (5))); - } - + operands[1] = force_reg (mode, operands[1]); + emit_insn (gen_fix_truncdi2_dfp (operands[0], operands[1], + GEN_INT (9))); DONE; }) -(define_insn "fix_truncdfsi2_ibm" - [(set (match_operand:SI 0 "register_operand" "=d") - (fix:SI (match_operand:DF 1 "nonimmediate_operand" "+f"))) - (use (match_operand:DI 2 "immediate_operand" "m")) - (use (match_operand:DI 3 "immediate_operand" "m")) - (use (match_operand:BLK 4 "memory_operand" "m")) +; cgxtr, cgdtr +(define_insn "fix_truncdi2_dfp" + [(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_HARD_FLOAT && TARGET_IBM_FLOAT" -{ - output_asm_insn ("sd\t%1,%2", operands); - output_asm_insn ("aw\t%1,%3", operands); - output_asm_insn ("std\t%1,%4", operands); - output_asm_insn ("xi\t%N4,128", operands); - return "l\t%0,%N4"; -} - [(set_attr "length" "20")]) + "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_HARD_DFP" + "cgtr\t%0,%h2,%1" + [(set_attr "op_type" "RRF") + (set_attr "type" "ftoi")]) + ; -; fix_truncsfsi2 instruction pattern(s). +; fix_trunctf(si|di)2 instruction pattern(s). ; -(define_expand "fix_truncsfsi2" - [(set (match_operand:SI 0 "register_operand" "") - (fix:SI (match_operand:SF 1 "nonimmediate_operand" "")))] +(define_expand "fix_trunctf2" + [(parallel [(set (match_operand:GPR 0 "register_operand" "") + (fix:GPR (match_operand:TF 1 "register_operand" ""))) + (unspec:GPR [(const_int 5)] UNSPEC_ROUND) + (clobber (reg:CC CC_REGNUM))])] "TARGET_HARD_FLOAT" -{ - if (TARGET_IBM_FLOAT) - { - /* Convert to DFmode and then use the POP algorithm. */ - rtx temp = gen_reg_rtx (DFmode); - emit_insn (gen_extendsfdf2 (temp, operands[1])); - emit_insn (gen_fix_truncdfsi2 (operands[0], temp)); - } - else - { - operands[1] = force_reg (SFmode, operands[1]); - emit_insn (gen_fix_truncsfsi2_ieee (operands[0], operands[1], GEN_INT (5))); - } + "") - DONE; -}) ; -; floatdi(df|sf)2 instruction pattern(s). +; float(si|di)(tf|df|sf|td|dd)2 instruction pattern(s). ; +; cxgbr, cdgbr, cegbr, cxgtr, cdgtr (define_insn "floatdi2" - [(set (match_operand:FPR 0 "register_operand" "=f") - (float:FPR (match_operand:DI 1 "register_operand" "d")))] - "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "cgbr\t%0,%1" + [(set (match_operand:FP 0 "register_operand" "=f") + (float:FP (match_operand:DI 1 "register_operand" "d")))] + "TARGET_64BIT && TARGET_HARD_FLOAT" + "cgr\t%0,%1" [(set_attr "op_type" "RRE") (set_attr "type" "itof" )]) -; -; floatsidf2 instruction pattern(s). -; - -(define_expand "floatsidf2" - [(set (match_operand:DF 0 "register_operand" "") - (float:DF (match_operand:SI 1 "register_operand" "")))] +; cxfbr, cdfbr, cefbr +(define_insn "floatsi2" + [(set (match_operand:BFP 0 "register_operand" "=f") + (float:BFP (match_operand:SI 1 "register_operand" "d")))] "TARGET_HARD_FLOAT" -{ - if (TARGET_IBM_FLOAT) - { - /* This is the algorithm from POP chapter A.5.7.1. */ - - rtx temp = assign_stack_local (BLKmode, 8, BITS_PER_WORD); - rtx two31 = s390_gen_rtx_const_DI (0x4e000000, 0x80000000); - - emit_insn (gen_floatsidf2_ibm (operands[0], operands[1], two31, temp)); - DONE; - } -}) - -(define_insn "floatsidf2_ieee" - [(set (match_operand:DF 0 "register_operand" "=f") - (float:DF (match_operand:SI 1 "register_operand" "d")))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "cdfbr\t%0,%1" + "cfbr\t%0,%1" [(set_attr "op_type" "RRE") (set_attr "type" "itof" )]) -(define_insn "floatsidf2_ibm" - [(set (match_operand:DF 0 "register_operand" "=f") - (float:DF (match_operand:SI 1 "register_operand" "d"))) - (use (match_operand:DI 2 "immediate_operand" "m")) - (use (match_operand:BLK 3 "memory_operand" "m")) - (clobber (reg:CC CC_REGNUM))] - "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" -{ - output_asm_insn ("st\t%1,%N3", operands); - output_asm_insn ("xi\t%N3,128", operands); - output_asm_insn ("mvc\t%O3(4,%R3),%2", operands); - output_asm_insn ("ld\t%0,%3", operands); - return "sd\t%0,%2"; -} - [(set_attr "length" "20")]) ; -; floatsisf2 instruction pattern(s). +; truncdfsf2 instruction pattern(s). ; -(define_expand "floatsisf2" - [(set (match_operand:SF 0 "register_operand" "") - (float:SF (match_operand:SI 1 "register_operand" "")))] - "TARGET_HARD_FLOAT" -{ - if (TARGET_IBM_FLOAT) - { - /* Use the POP algorithm to convert to DFmode and then truncate. */ - rtx temp = gen_reg_rtx (DFmode); - emit_insn (gen_floatsidf2 (temp, operands[1])); - emit_insn (gen_truncdfsf2 (operands[0], temp)); - DONE; - } -}) - -(define_insn "floatsisf2_ieee" +(define_insn "truncdfsf2" [(set (match_operand:SF 0 "register_operand" "=f") - (float:SF (match_operand:SI 1 "register_operand" "d")))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "cefbr\t%0,%1" - [(set_attr "op_type" "RRE") - (set_attr "type" "itof" )]) + (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))] + "TARGET_HARD_FLOAT" + "ledbr\t%0,%1" + [(set_attr "op_type" "RRE") + (set_attr "type" "ftruncdf")]) ; -; truncdfsf2 instruction pattern(s). +; trunctf(df|sf)2 instruction pattern(s). ; -(define_expand "truncdfsf2" - [(set (match_operand:SF 0 "register_operand" "") - (float_truncate:SF (match_operand:DF 1 "register_operand" "")))] +; ldxbr, lexbr +(define_insn "trunctf2" + [(set (match_operand:DSF 0 "register_operand" "=f") + (float_truncate:DSF (match_operand:TF 1 "register_operand" "f"))) + (clobber (match_scratch:TF 2 "=f"))] "TARGET_HARD_FLOAT" - "") + "lxbr\t%2,%1\;lr\t%0,%2" + [(set_attr "length" "6") + (set_attr "type" "ftrunctf")]) -(define_insn "truncdfsf2_ieee" - [(set (match_operand:SF 0 "register_operand" "=f") - (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "ledbr\t%0,%1" - [(set_attr "op_type" "RRE")]) +; +; trunctddd2 and truncddsd2 instruction pattern(s). +; -(define_insn "truncdfsf2_ibm" - [(set (match_operand:SF 0 "register_operand" "=f,f") - (float_truncate:SF (match_operand:DF 1 "nonimmediate_operand" "f,R")))] - "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" +(define_insn "trunctddd2" + [(set (match_operand:DD 0 "register_operand" "=f") + (float_truncate:DD (match_operand:TD 1 "register_operand" "f"))) + (clobber (match_scratch:TD 2 "=f"))] + "TARGET_HARD_FLOAT && TARGET_HARD_DFP" + "ldxtr\t%2,0,%1,0\;ldr\t%0,%2" + [(set_attr "length" "6") + (set_attr "type" "ftrunctf")]) + +(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")]) + +; +; extend(sf|df)(df|tf)2 instruction pattern(s). +; + +; ldebr, ldeb, lxdbr, lxdb, lxebr, lxeb +(define_insn "extend2" + [(set (match_operand:BFP 0 "register_operand" "=f,f") + (float_extend:BFP (match_operand:DSF 1 "nonimmediate_operand" "f,R")))] + "TARGET_HARD_FLOAT + && GET_MODE_SIZE (mode) > GET_MODE_SIZE (mode)" "@ - ler\t%0,%1 - le\t%0,%1" - [(set_attr "op_type" "RR,RX") - (set_attr "type" "floadsf")]) + lbr\t%0,%1 + lb\t%0,%1" + [(set_attr "op_type" "RRE,RXE") + (set_attr "type" "fsimp, fload")]) ; -; extendsfdf2 instruction pattern(s). +; extendddtd2 and extendsddd2 instruction pattern(s). ; -(define_expand "extendsfdf2" - [(set (match_operand:DF 0 "register_operand" "") - (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))] - "TARGET_HARD_FLOAT" +(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")]) + +; Binary <-> Decimal floating point trunc patterns +; + +(define_insn "*trunc2" + [(set (reg:DFP_ALL FPR0_REGNUM) + (float_truncate:DFP_ALL (reg:BFP FPR2_REGNUM))) + (use (reg:SI GPR0_REGNUM)) + (clobber (reg:CC CC_REGNUM))] + "TARGET_HARD_FLOAT && TARGET_DFP" + "pfpo") + +(define_insn "*trunc2" + [(set (reg:BFP FPR0_REGNUM) + (float_truncate:BFP (reg:DFP_ALL FPR2_REGNUM))) + (use (reg:SI GPR0_REGNUM)) + (clobber (reg:CC CC_REGNUM))] + "TARGET_HARD_FLOAT && TARGET_DFP" + "pfpo") + +(define_expand "trunc2" + [(set (reg:BFP FPR2_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" "")) + (set (reg:SI GPR0_REGNUM) (match_dup 2)) + (parallel + [(set (reg:DFP_ALL FPR0_REGNUM) + (float_truncate:DFP_ALL (reg:BFP FPR2_REGNUM))) + (use (reg:SI GPR0_REGNUM)) + (clobber (reg:CC CC_REGNUM))]) + (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "") + (reg:DFP_ALL FPR0_REGNUM))] + "TARGET_HARD_FLOAT && TARGET_DFP + && GET_MODE_SIZE (mode) > GET_MODE_SIZE (mode)" { - if (TARGET_IBM_FLOAT) - { - emit_insn (gen_extendsfdf2_ibm (operands[0], operands[1])); - DONE; - } + HOST_WIDE_INT flags; + + flags = (PFPO_CONVERT | + PFPO_OP_TYPE_ << PFPO_OP0_TYPE_SHIFT | + PFPO_OP_TYPE_ << PFPO_OP1_TYPE_SHIFT); + + operands[2] = GEN_INT (flags); }) -(define_insn "extendsfdf2_ieee" - [(set (match_operand:DF 0 "register_operand" "=f,f") - (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,R")))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "@ - ldebr\t%0,%1 - ldeb\t%0,%1" - [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "floadsf")]) +(define_expand "trunc2" + [(set (reg:DFP_ALL FPR2_REGNUM) + (match_operand:DFP_ALL 1 "nonimmediate_operand" "")) + (set (reg:SI GPR0_REGNUM) (match_dup 2)) + (parallel + [(set (reg:BFP FPR0_REGNUM) (float_truncate:BFP (reg:DFP_ALL FPR2_REGNUM))) + (use (reg:SI GPR0_REGNUM)) + (clobber (reg:CC CC_REGNUM))]) + (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))] + "TARGET_HARD_FLOAT && TARGET_DFP + && GET_MODE_SIZE (mode) >= GET_MODE_SIZE (mode)" +{ + HOST_WIDE_INT flags; + + flags = (PFPO_CONVERT | + PFPO_OP_TYPE_ << PFPO_OP0_TYPE_SHIFT | + PFPO_OP_TYPE_ << PFPO_OP1_TYPE_SHIFT); + + operands[2] = GEN_INT (flags); +}) + +; +; Binary <-> Decimal floating point extend patterns +; -(define_insn "extendsfdf2_ibm" - [(set (match_operand:DF 0 "register_operand" "=f,f") - (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,R"))) +(define_insn "*extend2" + [(set (reg:DFP_ALL FPR0_REGNUM) (float_extend:DFP_ALL (reg:BFP FPR2_REGNUM))) + (use (reg:SI GPR0_REGNUM)) (clobber (reg:CC CC_REGNUM))] - "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" - "@ - sdr\t%0,%0\;ler\t%0,%1 - sdr\t%0,%0\;le\t%0,%1" - [(set_attr "length" "4,6") - (set_attr "type" "floadsf")]) + "TARGET_HARD_FLOAT && TARGET_DFP" + "pfpo") + +(define_insn "*extend2" + [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR2_REGNUM))) + (use (reg:SI GPR0_REGNUM)) + (clobber (reg:CC CC_REGNUM))] + "TARGET_HARD_FLOAT && TARGET_DFP" + "pfpo") + +(define_expand "extend2" + [(set (reg:BFP FPR2_REGNUM) (match_operand:BFP 1 "nonimmediate_operand" "")) + (set (reg:SI GPR0_REGNUM) (match_dup 2)) + (parallel + [(set (reg:DFP_ALL FPR0_REGNUM) + (float_extend:DFP_ALL (reg:BFP FPR2_REGNUM))) + (use (reg:SI GPR0_REGNUM)) + (clobber (reg:CC CC_REGNUM))]) + (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "") + (reg:DFP_ALL FPR0_REGNUM))] + "TARGET_HARD_FLOAT && TARGET_DFP + && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (mode)" +{ + HOST_WIDE_INT flags; + + flags = (PFPO_CONVERT | + PFPO_OP_TYPE_ << PFPO_OP0_TYPE_SHIFT | + PFPO_OP_TYPE_ << PFPO_OP1_TYPE_SHIFT); + + operands[2] = GEN_INT (flags); +}) + +(define_expand "extend2" + [(set (reg:DFP_ALL FPR2_REGNUM) + (match_operand:DFP_ALL 1 "nonimmediate_operand" "")) + (set (reg:SI GPR0_REGNUM) (match_dup 2)) + (parallel + [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR2_REGNUM))) + (use (reg:SI GPR0_REGNUM)) + (clobber (reg:CC CC_REGNUM))]) + (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))] + "TARGET_HARD_FLOAT && TARGET_DFP + && GET_MODE_SIZE (mode) < GET_MODE_SIZE (mode)" +{ + HOST_WIDE_INT flags; + + flags = (PFPO_CONVERT | + PFPO_OP_TYPE_ << PFPO_OP0_TYPE_SHIFT | + PFPO_OP_TYPE_ << PFPO_OP1_TYPE_SHIFT); + + operands[2] = GEN_INT (flags); +}) ;; @@ -3275,8 +3635,9 @@ (match_dup 7))) (set (match_dup 6) (plus:DI (match_dup 7) (match_dup 8)))]) (parallel - [(set (match_dup 3) (plus:DI (plus:DI (match_dup 4) (match_dup 5)) - (ltu:DI (reg:CCL1 CC_REGNUM) (const_int 0)))) + [(set (match_dup 3) (plus:DI + (plus:DI (ltu:DI (reg:CCL1 CC_REGNUM) (const_int 0)) + (match_dup 4)) (match_dup 5))) (clobber (reg:CC CC_REGNUM))])] "operands[3] = operand_subword (operands[0], 0, 0, TImode); operands[4] = operand_subword (operands[1], 0, 0, TImode); @@ -3289,6 +3650,15 @@ ; adddi3 instruction pattern(s). ; +(define_expand "adddi3" + [(parallel + [(set (match_operand:DI 0 "register_operand" "") + (plus:DI (match_operand:DI 1 "nonimmediate_operand" "") + (match_operand:DI 2 "general_operand" ""))) + (clobber (reg:CC CC_REGNUM))])] + "" + "") + (define_insn "*adddi3_sign" [(set (match_operand:DI 0 "register_operand" "=d,d") (plus:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,m")) @@ -3336,128 +3706,6 @@ algf\t%0,%2" [(set_attr "op_type" "RRE,RXY")]) -(define_insn "*adddi3_imm_cc" - [(set (reg CC_REGNUM) - (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") - (match_operand:DI 2 "const_int_operand" "K,Os")) - (const_int 0))) - (set (match_operand:DI 0 "register_operand" "=d,d") - (plus:DI (match_dup 1) (match_dup 2)))] - "TARGET_64BIT - && s390_match_ccmode (insn, CCAmode) - && (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\") - || CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'O', \"Os\"))" - "@ - aghi\t%0,%h2 - agfi\t%0,%2" - [(set_attr "op_type" "RI,RIL")]) - -(define_insn "*adddi3_carry1_cc" - [(set (reg CC_REGNUM) - (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0") - (match_operand:DI 2 "general_operand" "d,Op,On,m")) - (match_dup 1))) - (set (match_operand:DI 0 "register_operand" "=d,d,d,d") - (plus:DI (match_dup 1) (match_dup 2)))] - "s390_match_ccmode (insn, CCL1mode) && TARGET_64BIT" - "@ - algr\t%0,%2 - algfi\t%0,%2 - slgfi\t%0,%n2 - alg\t%0,%2" - [(set_attr "op_type" "RRE,RIL,RIL,RXY")]) - -(define_insn "*adddi3_carry1_cconly" - [(set (reg CC_REGNUM) - (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") - (match_operand:DI 2 "general_operand" "d,m")) - (match_dup 1))) - (clobber (match_scratch:DI 0 "=d,d"))] - "s390_match_ccmode (insn, CCL1mode) && TARGET_64BIT" - "@ - algr\t%0,%2 - alg\t%0,%2" - [(set_attr "op_type" "RRE,RXY")]) - -(define_insn "*adddi3_carry2_cc" - [(set (reg CC_REGNUM) - (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0") - (match_operand:DI 2 "general_operand" "d,Op,On,m")) - (match_dup 2))) - (set (match_operand:DI 0 "register_operand" "=d,d,d,d") - (plus:DI (match_dup 1) (match_dup 2)))] - "s390_match_ccmode (insn, CCL1mode) && TARGET_64BIT" - "@ - algr\t%0,%2 - algfi\t%0,%2 - slgfi\t%0,%n2 - alg\t%0,%2" - [(set_attr "op_type" "RRE,RIL,RIL,RXY")]) - -(define_insn "*adddi3_carry2_cconly" - [(set (reg CC_REGNUM) - (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") - (match_operand:DI 2 "general_operand" "d,m")) - (match_dup 2))) - (clobber (match_scratch:DI 0 "=d,d"))] - "s390_match_ccmode (insn, CCL1mode) && TARGET_64BIT" - "@ - algr\t%0,%2 - alg\t%0,%2" - [(set_attr "op_type" "RRE,RXY")]) - -(define_insn "*adddi3_cc" - [(set (reg CC_REGNUM) - (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0") - (match_operand:DI 2 "general_operand" "d,Op,On,m")) - (const_int 0))) - (set (match_operand:DI 0 "register_operand" "=d,d,d,d") - (plus:DI (match_dup 1) (match_dup 2)))] - "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT" - "@ - algr\t%0,%2 - algfi\t%0,%2 - slgfi\t%0,%n2 - alg\t%0,%2" - [(set_attr "op_type" "RRE,RIL,RIL,RXY")]) - -(define_insn "*adddi3_cconly" - [(set (reg CC_REGNUM) - (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") - (match_operand:DI 2 "general_operand" "d,m")) - (const_int 0))) - (clobber (match_scratch:DI 0 "=d,d"))] - "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT" - "@ - algr\t%0,%2 - alg\t%0,%2" - [(set_attr "op_type" "RRE,RXY")]) - -(define_insn "*adddi3_cconly2" - [(set (reg CC_REGNUM) - (compare (match_operand:DI 1 "nonimmediate_operand" "%0,0") - (neg:SI (match_operand:DI 2 "general_operand" "d,m")))) - (clobber (match_scratch:DI 0 "=d,d"))] - "s390_match_ccmode(insn, CCLmode) && TARGET_64BIT" - "@ - algr\t%0,%2 - alg\t%0,%2" - [(set_attr "op_type" "RRE,RXY")]) - -(define_insn "*adddi3_64" - [(set (match_operand:DI 0 "register_operand" "=d,d,d,d,d") - (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0,0") - (match_operand:DI 2 "general_operand" "d,K,Op,On,m") ) ) - (clobber (reg:CC CC_REGNUM))] - "TARGET_64BIT" - "@ - agr\t%0,%2 - aghi\t%0,%h2 - algfi\t%0,%2 - slgfi\t%0,%n2 - ag\t%0,%2" - [(set_attr "op_type" "RRE,RI,RIL,RIL,RXY")]) - (define_insn_and_split "*adddi3_31z" [(set (match_operand:DI 0 "register_operand" "=&d") (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0") @@ -3472,8 +3720,9 @@ (match_dup 7))) (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))]) (parallel - [(set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5)) - (ltu:SI (reg:CCL1 CC_REGNUM) (const_int 0)))) + [(set (match_dup 3) (plus:SI + (plus:SI (ltu:SI (reg:CCL1 CC_REGNUM) (const_int 0)) + (match_dup 4)) (match_dup 5))) (clobber (reg:CC CC_REGNUM))])] "operands[3] = operand_subword (operands[0], 0, 0, DImode); operands[4] = operand_subword (operands[1], 0, 0, DImode); @@ -3514,219 +3763,218 @@ operands[8] = operand_subword (operands[2], 1, 0, DImode); operands[9] = gen_label_rtx ();") -(define_expand "adddi3" +; +; addsi3 instruction pattern(s). +; + +(define_expand "addsi3" [(parallel - [(set (match_operand:DI 0 "register_operand" "") - (plus:DI (match_operand:DI 1 "nonimmediate_operand" "") - (match_operand:DI 2 "general_operand" ""))) + [(set (match_operand:SI 0 "register_operand" "") + (plus:SI (match_operand:SI 1 "nonimmediate_operand" "") + (match_operand:SI 2 "general_operand" ""))) (clobber (reg:CC CC_REGNUM))])] "" "") +(define_insn "*addsi3_sign" + [(set (match_operand:SI 0 "register_operand" "=d,d") + (plus:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T")) + (match_operand:SI 1 "register_operand" "0,0"))) + (clobber (reg:CC CC_REGNUM))] + "" + "@ + ah\t%0,%2 + ahy\t%0,%2" + [(set_attr "op_type" "RX,RXY")]) + ; -; addsi3 instruction pattern(s). +; add(di|si)3 instruction pattern(s). ; -(define_insn "*addsi3_imm_cc" - [(set (reg CC_REGNUM) - (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") - (match_operand:SI 2 "const_int_operand" "K,Os")) - (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=d,d") - (plus:SI (match_dup 1) (match_dup 2)))] - "s390_match_ccmode (insn, CCAmode) - && (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\") - || CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'O', \"Os\")) - && INTVAL (operands[2]) != -((HOST_WIDE_INT)1 << 31)" +; ar, ahi, alfi, slfi, a, ay, agr, aghi, algfi, slgfi, ag +(define_insn "*add3" + [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d,d") + (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0,0") + (match_operand:GPR 2 "general_operand" "d,K,Op,On,R,T") ) ) + (clobber (reg:CC CC_REGNUM))] + "" "@ - ahi\t%0,%h2 - afi\t%0,%2" - [(set_attr "op_type" "RI,RIL")]) + ar\t%0,%2 + ahi\t%0,%h2 + alfi\t%0,%2 + slfi\t%0,%n2 + a\t%0,%2 + a\t%0,%2" + [(set_attr "op_type" "RR,RI,RIL,RIL,RX,RXY")]) -(define_insn "*addsi3_carry1_cc" +; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg +(define_insn "*add3_carry1_cc" [(set (reg CC_REGNUM) - (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0") - (match_operand:SI 2 "general_operand" "d,Os,R,T")) + (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0") + (match_operand:GPR 2 "general_operand" "d,Op,On,R,T")) (match_dup 1))) - (set (match_operand:SI 0 "register_operand" "=d,d,d,d") - (plus:SI (match_dup 1) (match_dup 2)))] + (set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d") + (plus:GPR (match_dup 1) (match_dup 2)))] "s390_match_ccmode (insn, CCL1mode)" "@ - alr\t%0,%2 - alfi\t%0,%o2 - al\t%0,%2 - aly\t%0,%2" - [(set_attr "op_type" "RR,RIL,RX,RXY")]) + alr\t%0,%2 + alfi\t%0,%2 + slfi\t%0,%n2 + al\t%0,%2 + al\t%0,%2" + [(set_attr "op_type" "RR,RIL,RIL,RX,RXY")]) -(define_insn "*addsi3_carry1_cconly" +; alr, al, aly, algr, alg +(define_insn "*add3_carry1_cconly" [(set (reg CC_REGNUM) - (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T")) + (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0") + (match_operand:GPR 2 "general_operand" "d,R,T")) (match_dup 1))) - (clobber (match_scratch:SI 0 "=d,d,d"))] + (clobber (match_scratch:GPR 0 "=d,d,d"))] "s390_match_ccmode (insn, CCL1mode)" "@ - alr\t%0,%2 - al\t%0,%2 - aly\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) + alr\t%0,%2 + al\t%0,%2 + al\t%0,%2" + [(set_attr "op_type" "RR,RX,RXY")]) -(define_insn "*addsi3_carry2_cc" +; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg +(define_insn "*add3_carry2_cc" [(set (reg CC_REGNUM) - (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0") - (match_operand:SI 2 "general_operand" "d,Os,R,T")) + (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0") + (match_operand:GPR 2 "general_operand" "d,Op,On,R,T")) (match_dup 2))) - (set (match_operand:SI 0 "register_operand" "=d,d,d,d") - (plus:SI (match_dup 1) (match_dup 2)))] + (set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d") + (plus:GPR (match_dup 1) (match_dup 2)))] "s390_match_ccmode (insn, CCL1mode)" "@ - alr\t%0,%2 - alfi\t%0,%o2 - al\t%0,%2 - aly\t%0,%2" - [(set_attr "op_type" "RR,RIL,RX,RXY")]) + alr\t%0,%2 + alfi\t%0,%2 + slfi\t%0,%n2 + al\t%0,%2 + al\t%0,%2" + [(set_attr "op_type" "RR,RIL,RIL,RX,RXY")]) -(define_insn "*addsi3_carry2_cconly" +; alr, al, aly, algr, alg +(define_insn "*add3_carry2_cconly" [(set (reg CC_REGNUM) - (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T")) + (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0") + (match_operand:GPR 2 "general_operand" "d,R,T")) (match_dup 2))) - (clobber (match_scratch:SI 0 "=d,d,d"))] + (clobber (match_scratch:GPR 0 "=d,d,d"))] "s390_match_ccmode (insn, CCL1mode)" "@ - alr\t%0,%2 - al\t%0,%2 - aly\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) + alr\t%0,%2 + al\t%0,%2 + al\t%0,%2" + [(set_attr "op_type" "RR,RX,RXY")]) -(define_insn "*addsi3_cc" - [(set (reg CC_REGNUM) - (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0") - (match_operand:SI 2 "general_operand" "d,Os,R,T")) - (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=d,d,d,d") - (plus:SI (match_dup 1) (match_dup 2)))] - "s390_match_ccmode (insn, CCLmode)" - "@ - alr\t%0,%2 - alfi\t%0,%o2 - al\t%0,%2 - aly\t%0,%2" - [(set_attr "op_type" "RR,RIL,RX,RXY")]) - -(define_insn "*addsi3_cconly" +; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg +(define_insn "*add3_cc" [(set (reg CC_REGNUM) - (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T")) + (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0") + (match_operand:GPR 2 "general_operand" "d,Op,On,R,T")) (const_int 0))) - (clobber (match_scratch:SI 0 "=d,d,d"))] + (set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d") + (plus:GPR (match_dup 1) (match_dup 2)))] "s390_match_ccmode (insn, CCLmode)" "@ - alr\t%0,%2 - al\t%0,%2 - aly\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) + alr\t%0,%2 + alfi\t%0,%2 + slfi\t%0,%n2 + al\t%0,%2 + al\t%0,%2" + [(set_attr "op_type" "RR,RIL,RIL,RX,RXY")]) -(define_insn "*addsi3_cconly2" +; alr, al, aly, algr, alg +(define_insn "*add3_cconly" [(set (reg CC_REGNUM) - (compare (match_operand:SI 1 "nonimmediate_operand" "%0,0,0") - (neg:SI (match_operand:SI 2 "general_operand" "d,R,T")))) - (clobber (match_scratch:SI 0 "=d,d,d"))] + (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0") + (match_operand:GPR 2 "general_operand" "d,R,T")) + (const_int 0))) + (clobber (match_scratch:GPR 0 "=d,d,d"))] "s390_match_ccmode (insn, CCLmode)" "@ - alr\t%0,%2 - al\t%0,%2 - aly\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) - -(define_insn "*addsi3_sign" - [(set (match_operand:SI 0 "register_operand" "=d,d") - (plus:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T")) - (match_operand:SI 1 "register_operand" "0,0"))) - (clobber (reg:CC CC_REGNUM))] - "" - "@ - ah\t%0,%2 - ahy\t%0,%2" - [(set_attr "op_type" "RX,RXY")]) + alr\t%0,%2 + al\t%0,%2 + al\t%0,%2" + [(set_attr "op_type" "RR,RX,RXY")]) -(define_insn "addsi3" - [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d") - (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0") - (match_operand:SI 2 "general_operand" "d,K,Os,R,T"))) - (clobber (reg:CC CC_REGNUM))] - "" +; alr, al, aly, algr, alg +(define_insn "*add3_cconly2" + [(set (reg CC_REGNUM) + (compare (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0") + (neg:GPR (match_operand:GPR 2 "general_operand" "d,R,T")))) + (clobber (match_scratch:GPR 0 "=d,d,d"))] + "s390_match_ccmode(insn, CCLmode)" + "@ + alr\t%0,%2 + al\t%0,%2 + al\t%0,%2" + [(set_attr "op_type" "RR,RX,RXY")]) + +; ahi, afi, aghi, agfi +(define_insn "*add3_imm_cc" + [(set (reg CC_REGNUM) + (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0") + (match_operand:GPR 2 "const_int_operand" "K,Os")) + (const_int 0))) + (set (match_operand:GPR 0 "register_operand" "=d,d") + (plus:GPR (match_dup 1) (match_dup 2)))] + "s390_match_ccmode (insn, CCAmode) + && (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\") + || CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'O', \"Os\")) + && INTVAL (operands[2]) != -((HOST_WIDE_INT)1 << (GET_MODE_BITSIZE(mode) - 1))" "@ - ar\t%0,%2 - ahi\t%0,%h2 - afi\t%0,%2 - a\t%0,%2 - ay\t%0,%2" - [(set_attr "op_type" "RR,RI,RIL,RX,RXY")]) + ahi\t%0,%h2 + afi\t%0,%2" + [(set_attr "op_type" "RI,RIL")]) ; -; add(df|sf)3 instruction pattern(s). +; add(tf|df|sf|td|dd)3 instruction pattern(s). ; -(define_expand "add3" - [(parallel - [(set (match_operand:FPR 0 "register_operand" "=f,f") - (plus:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0") - (match_operand:FPR 2 "general_operand" "f,R"))) - (clobber (reg:CC CC_REGNUM))])] - "TARGET_HARD_FLOAT" - "") - -(define_insn "*add3" - [(set (match_operand:FPR 0 "register_operand" "=f,f") - (plus:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0") - (match_operand:FPR 2 "general_operand" "f,R"))) +; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr +(define_insn "add3" + [(set (match_operand:FP 0 "register_operand" "=f, f") + (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%,0") + (match_operand:FP 2 "general_operand" " f,"))) (clobber (reg:CC CC_REGNUM))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" + "TARGET_HARD_FLOAT" "@ - abr\t%0,%2 - ab\t%0,%2" - [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fsimp")]) + ar\t%0,%2 + ab\t%0,%2" + [(set_attr "op_type" ",RXE") + (set_attr "type" "fsimp")]) +; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr (define_insn "*add3_cc" [(set (reg CC_REGNUM) - (compare (plus:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0") - (match_operand:FPR 2 "general_operand" "f,R")) - (match_operand:FPR 3 "const0_operand" ""))) - (set (match_operand:FPR 0 "register_operand" "=f,f") - (plus:FPR (match_dup 1) (match_dup 2)))] - "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "@ - abr\t%0,%2 - ab\t%0,%2" - [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fsimp")]) - + (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%,0") + (match_operand:FP 2 "general_operand" " f,")) + (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" + "@ + ar\t%0,%2 + ab\t%0,%2" + [(set_attr "op_type" ",RXE") + (set_attr "type" "fsimp")]) + +; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr (define_insn "*add3_cconly" [(set (reg CC_REGNUM) - (compare (plus:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0") - (match_operand:FPR 2 "general_operand" "f,R")) - (match_operand:FPR 3 "const0_operand" ""))) - (clobber (match_scratch:FPR 0 "=f,f"))] - "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "@ - abr\t%0,%2 - ab\t%0,%2" - [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fsimp")]) - -(define_insn "*add3_ibm" - [(set (match_operand:FPR 0 "register_operand" "=f,f") - (plus:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0") - (match_operand:FPR 2 "general_operand" "f,R"))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" + (compare (plus:FP (match_operand:FP 1 "nonimmediate_operand" "%,0") + (match_operand:FP 2 "general_operand" " f,")) + (match_operand:FP 3 "const0_operand" ""))) + (clobber (match_scratch:FP 0 "=f,f"))] + "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT" "@ - ar\t%0,%2 - a\t%0,%2" - [(set_attr "op_type" "RR,RX") - (set_attr "type" "fsimp")]) + ar\t%0,%2 + ab\t%0,%2" + [(set_attr "op_type" ",RXE") + (set_attr "type" "fsimp")]) ;; @@ -3765,6 +4013,15 @@ ; subdi3 instruction pattern(s). ; +(define_expand "subdi3" + [(parallel + [(set (match_operand:DI 0 "register_operand" "") + (minus:DI (match_operand:DI 1 "register_operand" "") + (match_operand:DI 2 "general_operand" ""))) + (clobber (reg:CC CC_REGNUM))])] + "" + "") + (define_insn "*subdi3_sign" [(set (match_operand:DI 0 "register_operand" "=d,d") (minus:DI (match_operand:DI 1 "register_operand" "0,0") @@ -3812,90 +4069,6 @@ slgf\t%0,%2" [(set_attr "op_type" "RRE,RXY")]) -(define_insn "*subdi3_borrow_cc" - [(set (reg CC_REGNUM) - (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0") - (match_operand:DI 2 "general_operand" "d,m")) - (match_dup 1))) - (set (match_operand:DI 0 "register_operand" "=d,d") - (minus:DI (match_dup 1) (match_dup 2)))] - "s390_match_ccmode (insn, CCL2mode) && TARGET_64BIT" - "@ - slgr\t%0,%2 - slg\t%0,%2" - [(set_attr "op_type" "RRE,RXY")]) - -(define_insn "*subdi3_borrow_cconly" - [(set (reg CC_REGNUM) - (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0") - (match_operand:DI 2 "general_operand" "d,m")) - (match_dup 1))) - (clobber (match_scratch:DI 0 "=d,d"))] - "s390_match_ccmode (insn, CCL2mode) && TARGET_64BIT" - "@ - slgr\t%0,%2 - slg\t%0,%2" - [(set_attr "op_type" "RRE,RXY")]) - -(define_insn "*subdi3_cc" - [(set (reg CC_REGNUM) - (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0") - (match_operand:DI 2 "general_operand" "d,m")) - (const_int 0))) - (set (match_operand:DI 0 "register_operand" "=d,d") - (minus:DI (match_dup 1) (match_dup 2)))] - "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT" - "@ - slgr\t%0,%2 - slg\t%0,%2" - [(set_attr "op_type" "RRE,RXY")]) - -(define_insn "*subdi3_cc2" - [(set (reg CC_REGNUM) - (compare (match_operand:DI 1 "register_operand" "0,0") - (match_operand:DI 2 "general_operand" "d,m"))) - (set (match_operand:DI 0 "register_operand" "=d,d") - (minus:DI (match_dup 1) (match_dup 2)))] - "s390_match_ccmode (insn, CCL3mode) && TARGET_64BIT" - "@ - slgr\t%0,%2 - slg\t%0,%2" - [(set_attr "op_type" "RRE,RXY")]) - -(define_insn "*subdi3_cconly" - [(set (reg CC_REGNUM) - (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0") - (match_operand:DI 2 "general_operand" "d,m")) - (const_int 0))) - (clobber (match_scratch:DI 0 "=d,d"))] - "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT" - "@ - slgr\t%0,%2 - slg\t%0,%2" - [(set_attr "op_type" "RRE,RXY")]) - -(define_insn "*subdi3_cconly2" - [(set (reg CC_REGNUM) - (compare (match_operand:DI 1 "register_operand" "0,0") - (match_operand:DI 2 "general_operand" "d,m"))) - (clobber (match_scratch:DI 0 "=d,d"))] - "s390_match_ccmode (insn, CCL3mode) && TARGET_64BIT" - "@ - slgr\t%0,%2 - slg\t%0,%2" - [(set_attr "op_type" "RRE,RXY")]) - -(define_insn "*subdi3_64" - [(set (match_operand:DI 0 "register_operand" "=d,d") - (minus:DI (match_operand:DI 1 "register_operand" "0,0") - (match_operand:DI 2 "general_operand" "d,m") ) ) - (clobber (reg:CC CC_REGNUM))] - "TARGET_64BIT" - "@ - sgr\t%0,%2 - sg\t%0,%2" - [(set_attr "op_type" "RRE,RRE")]) - (define_insn_and_split "*subdi3_31z" [(set (match_operand:DI 0 "register_operand" "=&d") (minus:DI (match_operand:DI 1 "register_operand" "0") @@ -3952,185 +4125,177 @@ operands[8] = operand_subword (operands[2], 1, 0, DImode); operands[9] = gen_label_rtx ();") -(define_expand "subdi3" +; +; subsi3 instruction pattern(s). +; + +(define_expand "subsi3" [(parallel - [(set (match_operand:DI 0 "register_operand" "") - (minus:DI (match_operand:DI 1 "register_operand" "") - (match_operand:DI 2 "general_operand" ""))) + [(set (match_operand:SI 0 "register_operand" "") + (minus:SI (match_operand:SI 1 "register_operand" "") + (match_operand:SI 2 "general_operand" ""))) (clobber (reg:CC CC_REGNUM))])] "" "") +(define_insn "*subsi3_sign" + [(set (match_operand:SI 0 "register_operand" "=d,d") + (minus:SI (match_operand:SI 1 "register_operand" "0,0") + (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T")))) + (clobber (reg:CC CC_REGNUM))] + "" + "@ + sh\t%0,%2 + shy\t%0,%2" + [(set_attr "op_type" "RX,RXY")]) + ; -; subsi3 instruction pattern(s). +; sub(di|si)3 instruction pattern(s). ; -(define_insn "*subsi3_borrow_cc" +; sr, s, sy, sgr, sg +(define_insn "*sub3" + [(set (match_operand:GPR 0 "register_operand" "=d,d,d") + (minus:GPR (match_operand:GPR 1 "register_operand" "0,0,0") + (match_operand:GPR 2 "general_operand" "d,R,T") ) ) + (clobber (reg:CC CC_REGNUM))] + "" + "@ + sr\t%0,%2 + s\t%0,%2 + s\t%0,%2" + [(set_attr "op_type" "RR,RX,RXY")]) + +; slr, sl, sly, slgr, slg +(define_insn "*sub3_borrow_cc" [(set (reg CC_REGNUM) - (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T")) + (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,0,0") + (match_operand:GPR 2 "general_operand" "d,R,T")) (match_dup 1))) - (set (match_operand:SI 0 "register_operand" "=d,d,d") - (minus:SI (match_dup 1) (match_dup 2)))] + (set (match_operand:GPR 0 "register_operand" "=d,d,d") + (minus:GPR (match_dup 1) (match_dup 2)))] "s390_match_ccmode (insn, CCL2mode)" "@ - slr\t%0,%2 - sl\t%0,%2 - sly\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) + slr\t%0,%2 + sl\t%0,%2 + sl\t%0,%2" + [(set_attr "op_type" "RR,RX,RXY")]) -(define_insn "*subsi3_borrow_cconly" +; slr, sl, sly, slgr, slg +(define_insn "*sub3_borrow_cconly" [(set (reg CC_REGNUM) - (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T")) + (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,0,0") + (match_operand:GPR 2 "general_operand" "d,R,T")) (match_dup 1))) - (clobber (match_scratch:SI 0 "=d,d,d"))] + (clobber (match_scratch:GPR 0 "=d,d,d"))] "s390_match_ccmode (insn, CCL2mode)" "@ - slr\t%0,%2 - sl\t%0,%2 - sly\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) + slr\t%0,%2 + sl\t%0,%2 + sl\t%0,%2" + [(set_attr "op_type" "RR,RX,RXY")]) -(define_insn "*subsi3_cc" +; slr, sl, sly, slgr, slg +(define_insn "*sub3_cc" [(set (reg CC_REGNUM) - (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T")) + (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,0,0") + (match_operand:GPR 2 "general_operand" "d,R,T")) (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=d,d,d") - (minus:SI (match_dup 1) (match_dup 2)))] + (set (match_operand:GPR 0 "register_operand" "=d,d,d") + (minus:GPR (match_dup 1) (match_dup 2)))] "s390_match_ccmode (insn, CCLmode)" "@ - slr\t%0,%2 - sl\t%0,%2 - sly\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) + slr\t%0,%2 + sl\t%0,%2 + sl\t%0,%2" + [(set_attr "op_type" "RR,RX,RXY")]) -(define_insn "*subsi3_cc2" +; slr, sl, sly, slgr, slg +(define_insn "*sub3_cc2" [(set (reg CC_REGNUM) - (compare (match_operand:SI 1 "register_operand" "0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T"))) - (set (match_operand:SI 0 "register_operand" "=d,d,d") - (minus:SI (match_dup 1) (match_dup 2)))] + (compare (match_operand:GPR 1 "register_operand" "0,0,0") + (match_operand:GPR 2 "general_operand" "d,R,T"))) + (set (match_operand:GPR 0 "register_operand" "=d,d,d") + (minus:GPR (match_dup 1) (match_dup 2)))] "s390_match_ccmode (insn, CCL3mode)" "@ - slr\t%0,%2 - sl\t%0,%2 - sly\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) + slr\t%0,%2 + sl\t%0,%2 + sl\t%0,%2" + [(set_attr "op_type" "RR,RX,RXY")]) -(define_insn "*subsi3_cconly" +; slr, sl, sly, slgr, slg +(define_insn "*sub3_cconly" [(set (reg CC_REGNUM) - (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T")) + (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,0,0") + (match_operand:GPR 2 "general_operand" "d,R,T")) (const_int 0))) - (clobber (match_scratch:SI 0 "=d,d,d"))] + (clobber (match_scratch:GPR 0 "=d,d,d"))] "s390_match_ccmode (insn, CCLmode)" "@ - slr\t%0,%2 - sl\t%0,%2 - sly\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) + slr\t%0,%2 + sl\t%0,%2 + sl\t%0,%2" + [(set_attr "op_type" "RR,RX,RXY")]) -(define_insn "*subsi3_cconly2" +; slr, sl, sly, slgr, slg +(define_insn "*sub3_cconly2" [(set (reg CC_REGNUM) - (compare (match_operand:SI 1 "register_operand" "0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T"))) - (clobber (match_scratch:SI 0 "=d,d,d"))] + (compare (match_operand:GPR 1 "register_operand" "0,0,0") + (match_operand:GPR 2 "general_operand" "d,R,T"))) + (clobber (match_scratch:GPR 0 "=d,d,d"))] "s390_match_ccmode (insn, CCL3mode)" "@ - slr\t%0,%2 - sl\t%0,%2 - sly\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) - -(define_insn "*subsi3_sign" - [(set (match_operand:SI 0 "register_operand" "=d,d") - (minus:SI (match_operand:SI 1 "register_operand" "0,0") - (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T")))) - (clobber (reg:CC CC_REGNUM))] - "" - "@ - sh\t%0,%2 - shy\t%0,%2" - [(set_attr "op_type" "RX,RXY")]) - -(define_insn "subsi3" - [(set (match_operand:SI 0 "register_operand" "=d,d,d") - (minus:SI (match_operand:SI 1 "register_operand" "0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T"))) - (clobber (reg:CC CC_REGNUM))] - "" - "@ - sr\t%0,%2 - s\t%0,%2 - sy\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) - + slr\t%0,%2 + sl\t%0,%2 + sl\t%0,%2" + [(set_attr "op_type" "RR,RX,RXY")]) ; -; sub(df|sf)3 instruction pattern(s). +; sub(tf|df|sf|td|dd)3 instruction pattern(s). ; -(define_expand "sub3" - [(parallel - [(set (match_operand:FPR 0 "register_operand" "=f,f") - (minus:FPR (match_operand:FPR 1 "register_operand" "0,0") - (match_operand:FPR 2 "general_operand" "f,R"))) - (clobber (reg:CC CC_REGNUM))])] - "TARGET_HARD_FLOAT" - "") - -(define_insn "*sub3" - [(set (match_operand:FPR 0 "register_operand" "=f,f") - (minus:FPR (match_operand:FPR 1 "register_operand" "0,0") - (match_operand:FPR 2 "general_operand" "f,R"))) +; sxbr, sdbr, sebr, sxb, sdb, seb, sxtr, sdtr +(define_insn "sub3" + [(set (match_operand:FP 0 "register_operand" "=f, f") + (minus:FP (match_operand:FP 1 "register_operand" ",0") + (match_operand:FP 2 "general_operand" "f,"))) (clobber (reg:CC CC_REGNUM))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" + "TARGET_HARD_FLOAT" "@ - sbr\t%0,%2 - sb\t%0,%2" - [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fsimp")]) + sr\t%0,%2 + sb\t%0,%2" + [(set_attr "op_type" ",RXE") + (set_attr "type" "fsimp")]) +; sxbr, sdbr, sebr, sxb, sdb, seb, sxtr, sdtr (define_insn "*sub3_cc" [(set (reg CC_REGNUM) - (compare (minus:FPR (match_operand:FPR 1 "nonimmediate_operand" "0,0") - (match_operand:FPR 2 "general_operand" "f,R")) - (match_operand:FPR 3 "const0_operand" ""))) - (set (match_operand:FPR 0 "register_operand" "=f,f") - (minus:FPR (match_dup 1) (match_dup 2)))] - "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "@ - sbr\t%0,%2 - sb\t%0,%2" - [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fsimp")]) - + (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" ",0") + (match_operand:FP 2 "general_operand" "f,")) + (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" + "@ + sr\t%0,%2 + sb\t%0,%2" + [(set_attr "op_type" ",RXE") + (set_attr "type" "fsimp")]) + +; sxbr, sdbr, sebr, sxb, sdb, seb, sxtr, sdtr (define_insn "*sub3_cconly" [(set (reg CC_REGNUM) - (compare (minus:FPR (match_operand:FPR 1 "nonimmediate_operand" "0,0") - (match_operand:FPR 2 "general_operand" "f,R")) - (match_operand:FPR 3 "const0_operand" ""))) - (clobber (match_scratch:FPR 0 "=f,f"))] - "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "@ - sbr\t%0,%2 - sb\t%0,%2" - [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fsimp")]) - -(define_insn "*sub3_ibm" - [(set (match_operand:FPR 0 "register_operand" "=f,f") - (minus:FPR (match_operand:FPR 1 "register_operand" "0,0") - (match_operand:FPR 2 "general_operand" "f,R"))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" + (compare (minus:FP (match_operand:FP 1 "nonimmediate_operand" ",0") + (match_operand:FP 2 "general_operand" "f,")) + (match_operand:FP 3 "const0_operand" ""))) + (clobber (match_scratch:FP 0 "=f,f"))] + "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT" "@ - sr\t%0,%2 - s\t%0,%2" - [(set_attr "op_type" "RR,RX") - (set_attr "type" "fsimp")]) + sr\t%0,%2 + sb\t%0,%2" + [(set_attr "op_type" ",RXE") + (set_attr "type" "fsimp")]) ;; @@ -4141,26 +4306,97 @@ ; add(di|si)cc instruction pattern(s). ; +; the following 4 patterns are used when the result of an add with +; carry is checked for an overflow condition + +; op1 + op2 + c < op1 + +; alcr, alc, alcgr, alcg +(define_insn "*add3_alc_carry1_cc" + [(set (reg CC_REGNUM) + (compare + (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "") + (match_operand:GPR 1 "nonimmediate_operand" "%0,0")) + (match_operand:GPR 2 "general_operand" "d,m")) + (match_dup 1))) + (set (match_operand:GPR 0 "register_operand" "=d,d") + (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))] + "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH" + "@ + alcr\t%0,%2 + alc\t%0,%2" + [(set_attr "op_type" "RRE,RXY")]) + +; alcr, alc, alcgr, alcg +(define_insn "*add3_alc_carry1_cconly" + [(set (reg CC_REGNUM) + (compare + (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "") + (match_operand:GPR 1 "nonimmediate_operand" "%0,0")) + (match_operand:GPR 2 "general_operand" "d,m")) + (match_dup 1))) + (clobber (match_scratch:GPR 0 "=d,d"))] + "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH" + "@ + alcr\t%0,%2 + alc\t%0,%2" + [(set_attr "op_type" "RRE,RXY")]) + +; op1 + op2 + c < op2 + +; alcr, alc, alcgr, alcg +(define_insn "*add3_alc_carry2_cc" + [(set (reg CC_REGNUM) + (compare + (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "") + (match_operand:GPR 1 "nonimmediate_operand" "%0,0")) + (match_operand:GPR 2 "general_operand" "d,m")) + (match_dup 2))) + (set (match_operand:GPR 0 "register_operand" "=d,d") + (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))] + "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH" + "@ + alcr\t%0,%2 + alc\t%0,%2" + [(set_attr "op_type" "RRE,RXY")]) + +; alcr, alc, alcgr, alcg +(define_insn "*add3_alc_carry2_cconly" + [(set (reg CC_REGNUM) + (compare + (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "") + (match_operand:GPR 1 "nonimmediate_operand" "%0,0")) + (match_operand:GPR 2 "general_operand" "d,m")) + (match_dup 2))) + (clobber (match_scratch:GPR 0 "=d,d"))] + "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH" + "@ + alcr\t%0,%2 + alc\t%0,%2" + [(set_attr "op_type" "RRE,RXY")]) + +; alcr, alc, alcgr, alcg (define_insn "*add3_alc_cc" [(set (reg CC_REGNUM) (compare - (plus:GPR (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0") - (match_operand:GPR 2 "general_operand" "d,m")) - (match_operand:GPR 3 "s390_alc_comparison" "")) + (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "") + (match_operand:GPR 1 "nonimmediate_operand" "%0,0")) + (match_operand:GPR 2 "general_operand" "d,m")) (const_int 0))) (set (match_operand:GPR 0 "register_operand" "=d,d") - (plus:GPR (plus:GPR (match_dup 1) (match_dup 2)) (match_dup 3)))] + (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))] "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH" "@ alcr\t%0,%2 alc\t%0,%2" [(set_attr "op_type" "RRE,RXY")]) +; alcr, alc, alcgr, alcg (define_insn "*add3_alc" [(set (match_operand:GPR 0 "register_operand" "=d,d") - (plus:GPR (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0") - (match_operand:GPR 2 "general_operand" "d,m")) - (match_operand:GPR 3 "s390_alc_comparison" ""))) + (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "") + (match_operand:GPR 1 "nonimmediate_operand" "%0,0")) + (match_operand:GPR 2 "general_operand" "d,m"))) (clobber (reg:CC CC_REGNUM))] "TARGET_CPU_ZARCH" "@ @@ -4168,6 +4404,7 @@ alc\t%0,%2" [(set_attr "op_type" "RRE,RXY")]) +; slbr, slb, slbgr, slbg (define_insn "*sub3_slb_cc" [(set (reg CC_REGNUM) (compare @@ -4183,6 +4420,7 @@ slb\t%0,%2" [(set_attr "op_type" "RRE,RXY")]) +; slbr, slb, slbgr, slbg (define_insn "*sub3_slb" [(set (match_operand:GPR 0 "register_operand" "=d,d") (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0") @@ -4219,8 +4457,8 @@ "&& reload_completed" [(set (match_dup 0) (const_int 0)) (parallel - [(set (match_dup 0) (plus:GPR (plus:GPR (match_dup 0) (match_dup 0)) - (match_dup 1))) + [(set (match_dup 0) (plus:GPR (plus:GPR (match_dup 1) (match_dup 0)) + (match_dup 0))) (clobber (reg:CC CC_REGNUM))])] "") @@ -4371,59 +4609,44 @@ (set_attr "type" "imulsi")]) ; -; mul(df|sf)3 instruction pattern(s). +; mul(tf|df|sf|td|dd)3 instruction pattern(s). ; -(define_expand "mul3" - [(set (match_operand:FPR 0 "register_operand" "=f,f") - (mult:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0") - (match_operand:FPR 2 "general_operand" "f,R")))] +; mxbr mdbr, meebr, mxb, mxb, meeb, mdtr, mxtr +(define_insn "mul3" + [(set (match_operand:FP 0 "register_operand" "=f,f") + (mult:FP (match_operand:FP 1 "nonimmediate_operand" "%,0") + (match_operand:FP 2 "general_operand" "f,")))] "TARGET_HARD_FLOAT" - "") - -(define_insn "*mul3" - [(set (match_operand:FPR 0 "register_operand" "=f,f") - (mult:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0") - (match_operand:FPR 2 "general_operand" "f,R")))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "@ - mbr\t%0,%2 - mb\t%0,%2" - [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fmul")]) - -(define_insn "*mul3_ibm" - [(set (match_operand:FPR 0 "register_operand" "=f,f") - (mult:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0") - (match_operand:FPR 2 "general_operand" "f,R")))] - "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" "@ - mr\t%0,%2 - m\t%0,%2" - [(set_attr "op_type" "RR,RX") - (set_attr "type" "fmul")]) + mr\t%0,%2 + mb\t%0,%2" + [(set_attr "op_type" ",RXE") + (set_attr "type" "fmul")]) +; maxbr, madbr, maebr, maxb, madb, maeb (define_insn "*fmadd" - [(set (match_operand:FPR 0 "register_operand" "=f,f") - (plus:FPR (mult:FPR (match_operand:FPR 1 "register_operand" "%f,f") - (match_operand:FPR 2 "nonimmediate_operand" "f,R")) - (match_operand:FPR 3 "register_operand" "0,0")))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT && TARGET_FUSED_MADD" - "@ - mabr\t%0,%1,%2 - mab\t%0,%1,%2" + [(set (match_operand:DSF 0 "register_operand" "=f,f") + (plus:DSF (mult:DSF (match_operand:DSF 1 "register_operand" "%f,f") + (match_operand:DSF 2 "nonimmediate_operand" "f,R")) + (match_operand:DSF 3 "register_operand" "0,0")))] + "TARGET_HARD_FLOAT && TARGET_FUSED_MADD" + "@ + mabr\t%0,%1,%2 + mab\t%0,%1,%2" [(set_attr "op_type" "RRE,RXE") (set_attr "type" "fmul")]) +; msxbr, msdbr, msebr, msxb, msdb, mseb (define_insn "*fmsub" - [(set (match_operand:FPR 0 "register_operand" "=f,f") - (minus:FPR (mult:FPR (match_operand:FPR 1 "register_operand" "f,f") - (match_operand:FPR 2 "nonimmediate_operand" "f,R")) - (match_operand:FPR 3 "register_operand" "0,0")))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT && TARGET_FUSED_MADD" - "@ - msbr\t%0,%1,%2 - msb\t%0,%1,%2" + [(set (match_operand:DSF 0 "register_operand" "=f,f") + (minus:DSF (mult:DSF (match_operand:DSF 1 "register_operand" "f,f") + (match_operand:DSF 2 "nonimmediate_operand" "f,R")) + (match_operand:DSF 3 "register_operand" "0,0")))] + "TARGET_HARD_FLOAT && TARGET_FUSED_MADD" + "@ + msbr\t%0,%1,%2 + msb\t%0,%1,%2" [(set_attr "op_type" "RRE,RXE") (set_attr "type" "fmul")]) @@ -4453,12 +4676,10 @@ emit_insn (gen_divmodtidi3 (operands[4], operands[1], operands[2])); insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4])); - REG_NOTES (insn) = - gen_rtx_EXPR_LIST (REG_EQUAL, div_equal, REG_NOTES (insn)); + set_unique_reg_note (insn, REG_EQUAL, div_equal); insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4])); - REG_NOTES (insn) = - gen_rtx_EXPR_LIST (REG_EQUAL, mod_equal, REG_NOTES (insn)); + set_unique_reg_note (insn, REG_EQUAL, mod_equal); DONE; }) @@ -4524,17 +4745,15 @@ emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[4])); emit_move_insn (gen_lowpart (DImode, operands[4]), operands[1]); emit_move_insn (gen_highpart (DImode, operands[4]), const0_rtx); + insn = emit_insn (gen_udivmodtidi3 (operands[4], operands[4], operands[2])); - REG_NOTES (insn) = - gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn)); + set_unique_reg_note (insn, REG_EQUAL, equal); insn = emit_move_insn (operands[0], gen_lowpart (DImode, operands[4])); - REG_NOTES (insn) = - gen_rtx_EXPR_LIST (REG_EQUAL, div_equal, REG_NOTES (insn)); + set_unique_reg_note (insn, REG_EQUAL, div_equal); insn = emit_move_insn (operands[3], gen_highpart (DImode, operands[4])); - REG_NOTES (insn) = - gen_rtx_EXPR_LIST (REG_EQUAL, mod_equal, REG_NOTES (insn)); + set_unique_reg_note (insn, REG_EQUAL, mod_equal); DONE; }) @@ -4584,17 +4803,15 @@ operands[4] = gen_reg_rtx(DImode); emit_insn (gen_extendsidi2 (operands[4], operands[1])); + insn = emit_insn (gen_divmoddisi3 (operands[4], operands[4], operands[2])); - REG_NOTES (insn) = - gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn)); + set_unique_reg_note (insn, REG_EQUAL, equal); insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4])); - REG_NOTES (insn) = - gen_rtx_EXPR_LIST (REG_EQUAL, div_equal, REG_NOTES (insn)); + set_unique_reg_note (insn, REG_EQUAL, div_equal); insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4])); - REG_NOTES (insn) = - gen_rtx_EXPR_LIST (REG_EQUAL, mod_equal, REG_NOTES (insn)); + set_unique_reg_note (insn, REG_EQUAL, mod_equal); DONE; }) @@ -4646,17 +4863,15 @@ emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[4])); emit_move_insn (gen_lowpart (SImode, operands[4]), operands[1]); emit_move_insn (gen_highpart (SImode, operands[4]), const0_rtx); + insn = emit_insn (gen_udivmoddisi3 (operands[4], operands[4], operands[2])); - REG_NOTES (insn) = - gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn)); + set_unique_reg_note (insn, REG_EQUAL, equal); insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[4])); - REG_NOTES (insn) = - gen_rtx_EXPR_LIST (REG_EQUAL, div_equal, REG_NOTES (insn)); + set_unique_reg_note (insn, REG_EQUAL, div_equal); insn = emit_move_insn (operands[3], gen_highpart (SImode, operands[4])); - REG_NOTES (insn) = - gen_rtx_EXPR_LIST (REG_EQUAL, mod_equal, REG_NOTES (insn)); + set_unique_reg_note (insn, REG_EQUAL, mod_equal); DONE; }) @@ -4721,14 +4936,11 @@ emit_insn (gen_zero_extendsidi2 (operands[3], operands[1])); insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3], operands[2])); - REG_NOTES (insn) = - gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn)); + set_unique_reg_note (insn, REG_EQUAL, equal); insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[3])); - REG_NOTES (insn) = - gen_rtx_EXPR_LIST (REG_EQUAL, - udiv_equal, REG_NOTES (insn)); + set_unique_reg_note (insn, REG_EQUAL, udiv_equal); } } else @@ -4752,14 +4964,12 @@ emit_insn (gen_zero_extendsidi2 (operands[3], operands[1])); insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3], operands[2])); - REG_NOTES (insn) = - gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn)); + set_unique_reg_note (insn, REG_EQUAL, equal); insn = emit_move_insn (operands[0], gen_lowpart (SImode, operands[3])); - REG_NOTES (insn) = - gen_rtx_EXPR_LIST (REG_EQUAL, - udiv_equal, REG_NOTES (insn)); + set_unique_reg_note (insn, REG_EQUAL, udiv_equal); + emit_jump (label3); emit_label (label1); emit_move_insn (operands[0], operands[1]); @@ -4813,14 +5023,11 @@ emit_insn (gen_zero_extendsidi2 (operands[3], operands[1])); insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3], operands[2])); - REG_NOTES (insn) = - gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn)); + set_unique_reg_note (insn, REG_EQUAL, equal); insn = emit_move_insn (operands[0], gen_highpart (SImode, operands[3])); - REG_NOTES (insn) = - gen_rtx_EXPR_LIST (REG_EQUAL, - umod_equal, REG_NOTES (insn)); + set_unique_reg_note (insn, REG_EQUAL, umod_equal); } } else @@ -4844,14 +5051,12 @@ emit_insn (gen_zero_extendsidi2 (operands[3], operands[1])); insn = emit_insn (gen_divmoddisi3 (operands[3], operands[3], operands[2])); - REG_NOTES (insn) = - gen_rtx_EXPR_LIST (REG_EQUAL, equal, REG_NOTES (insn)); + set_unique_reg_note (insn, REG_EQUAL, equal); insn = emit_move_insn (operands[0], gen_highpart (SImode, operands[3])); - REG_NOTES (insn) = - gen_rtx_EXPR_LIST (REG_EQUAL, - umod_equal, REG_NOTES (insn)); + set_unique_reg_note (insn, REG_EQUAL, umod_equal); + emit_jump (label3); emit_label (label1); emit_move_insn (operands[0], const0_rtx); @@ -4867,34 +5072,17 @@ ; div(df|sf)3 instruction pattern(s). ; -(define_expand "div3" - [(set (match_operand:FPR 0 "register_operand" "=f,f") - (div:FPR (match_operand:FPR 1 "register_operand" "0,0") - (match_operand:FPR 2 "general_operand" "f,R")))] +; dxbr, ddbr, debr, dxb, ddb, deb, ddtr, dxtr +(define_insn "div3" + [(set (match_operand:FP 0 "register_operand" "=f,f") + (div:FP (match_operand:FP 1 "register_operand" ",0") + (match_operand:FP 2 "general_operand" "f,")))] "TARGET_HARD_FLOAT" - "") - -(define_insn "*div3" - [(set (match_operand:FPR 0 "register_operand" "=f,f") - (div:FPR (match_operand:FPR 1 "register_operand" "0,0") - (match_operand:FPR 2 "general_operand" "f,R")))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "@ - dbr\t%0,%2 - db\t%0,%2" - [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fdiv")]) - -(define_insn "*div3_ibm" - [(set (match_operand:FPR 0 "register_operand" "=f,f") - (div:FPR (match_operand:FPR 1 "register_operand" "0,0") - (match_operand:FPR 2 "general_operand" "f,R")))] - "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" "@ - dr\t%0,%2 - d\t%0,%2" - [(set_attr "op_type" "RR,RX") - (set_attr "type" "fdiv")]) + dr\t%0,%2 + db\t%0,%2" + [(set_attr "op_type" ",RXE") + (set_attr "type" "fdiv")]) ;; @@ -5530,7 +5718,7 @@ "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT" "@ xgr\t%0,%2 - xr\t%0,%2" + xg\t%0,%2" [(set_attr "op_type" "RRE,RXY")]) (define_insn "*xordi3_extimm" @@ -5802,6 +5990,7 @@ "lcgfr\t%0,%1" [(set_attr "op_type" "RRE")]) +; lcr, lcgr (define_insn "*neg2_cc" [(set (reg CC_REGNUM) (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d")) @@ -5811,7 +6000,8 @@ "s390_match_ccmode (insn, CCAmode)" "lcr\t%0,%1" [(set_attr "op_type" "RR")]) - + +; lcr, lcgr (define_insn "*neg2_cconly" [(set (reg CC_REGNUM) (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d")) @@ -5820,7 +6010,8 @@ "s390_match_ccmode (insn, CCAmode)" "lcr\t%0,%1" [(set_attr "op_type" "RR")]) - + +; lcr, lcgr (define_insn "*neg2" [(set (match_operand:GPR 0 "register_operand" "=d") (neg:GPR (match_operand:GPR 1 "register_operand" "d"))) @@ -5863,49 +6054,52 @@ (define_expand "neg2" [(parallel - [(set (match_operand:FPR 0 "register_operand" "=f") - (neg:FPR (match_operand:FPR 1 "register_operand" "f"))) + [(set (match_operand:BFP 0 "register_operand" "=f") + (neg:BFP (match_operand:BFP 1 "register_operand" "f"))) (clobber (reg:CC CC_REGNUM))])] "TARGET_HARD_FLOAT" "") +; lcxbr, lcdbr, lcebr (define_insn "*neg2_cc" [(set (reg CC_REGNUM) - (compare (neg:FPR (match_operand:FPR 1 "register_operand" "f")) - (match_operand:FPR 2 "const0_operand" ""))) - (set (match_operand:FPR 0 "register_operand" "=f") - (neg:FPR (match_dup 1)))] - "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "lcbr\t%0,%1" + (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f")) + (match_operand:BFP 2 "const0_operand" ""))) + (set (match_operand:BFP 0 "register_operand" "=f") + (neg:BFP (match_dup 1)))] + "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT" + "lcbr\t%0,%1" [(set_attr "op_type" "RRE") (set_attr "type" "fsimp")]) - + +; lcxbr, lcdbr, lcebr (define_insn "*neg2_cconly" [(set (reg CC_REGNUM) - (compare (neg:FPR (match_operand:FPR 1 "register_operand" "f")) - (match_operand:FPR 2 "const0_operand" ""))) - (clobber (match_scratch:FPR 0 "=f"))] - "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "lcbr\t%0,%1" + (compare (neg:BFP (match_operand:BFP 1 "register_operand" "f")) + (match_operand:BFP 2 "const0_operand" ""))) + (clobber (match_scratch:BFP 0 "=f"))] + "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT" + "lcbr\t%0,%1" [(set_attr "op_type" "RRE") (set_attr "type" "fsimp")]) - -(define_insn "*neg2" - [(set (match_operand:FPR 0 "register_operand" "=f") - (neg:FPR (match_operand:FPR 1 "register_operand" "f"))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "lcbr\t%0,%1" + +; lcdfr +(define_insn "*neg2_nocc" + [(set (match_operand:FP 0 "register_operand" "=f") + (neg:FP (match_operand:FP 1 "register_operand" "")))] + "TARGET_HARD_FLOAT && TARGET_DFP" + "lcdfr\t%0,%1" [(set_attr "op_type" "RRE") - (set_attr "type" "fsimp")]) + (set_attr "type" "fsimp")]) -(define_insn "*neg2_ibm" - [(set (match_operand:FPR 0 "register_operand" "=f") - (neg:FPR (match_operand:FPR 1 "register_operand" "f"))) +; lcxbr, lcdbr, lcebr +(define_insn "*neg2" + [(set (match_operand:BFP 0 "register_operand" "=f") + (neg:BFP (match_operand:BFP 1 "register_operand" "f"))) (clobber (reg:CC CC_REGNUM))] - "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" - "lcr\t%0,%1" - [(set_attr "op_type" "RR") + "TARGET_HARD_FLOAT" + "lcbr\t%0,%1" + [(set_attr "op_type" "RRE") (set_attr "type" "fsimp")]) @@ -5937,6 +6131,7 @@ "lpgfr\t%0,%1" [(set_attr "op_type" "RRE")]) +; lpr, lpgr (define_insn "*abs2_cc" [(set (reg CC_REGNUM) (compare (abs:GPR (match_operand:DI 1 "register_operand" "d")) @@ -5946,7 +6141,8 @@ "s390_match_ccmode (insn, CCAmode)" "lpr\t%0,%1" [(set_attr "op_type" "RR")]) - + +; lpr, lpgr (define_insn "*abs2_cconly" [(set (reg CC_REGNUM) (compare (abs:GPR (match_operand:GPR 1 "register_operand" "d")) @@ -5955,7 +6151,8 @@ "s390_match_ccmode (insn, CCAmode)" "lpr\t%0,%1" [(set_attr "op_type" "RR")]) - + +; lpr, lpgr (define_insn "abs2" [(set (match_operand:GPR 0 "register_operand" "=d") (abs:GPR (match_operand:GPR 1 "register_operand" "d"))) @@ -5970,50 +6167,54 @@ (define_expand "abs2" [(parallel - [(set (match_operand:FPR 0 "register_operand" "=f") - (abs:FPR (match_operand:FPR 1 "register_operand" "f"))) + [(set (match_operand:BFP 0 "register_operand" "=f") + (abs:BFP (match_operand:BFP 1 "register_operand" "f"))) (clobber (reg:CC CC_REGNUM))])] "TARGET_HARD_FLOAT" "") +; lpxbr, lpdbr, lpebr (define_insn "*abs2_cc" [(set (reg CC_REGNUM) - (compare (abs:FPR (match_operand:FPR 1 "register_operand" "f")) - (match_operand:FPR 2 "const0_operand" ""))) - (set (match_operand:FPR 0 "register_operand" "=f") - (abs:FPR (match_dup 1)))] - "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "lpbr\t%0,%1" + (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f")) + (match_operand:BFP 2 "const0_operand" ""))) + (set (match_operand:BFP 0 "register_operand" "=f") + (abs:BFP (match_dup 1)))] + "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT" + "lpbr\t%0,%1" [(set_attr "op_type" "RRE") (set_attr "type" "fsimp")]) - + +; lpxbr, lpdbr, lpebr (define_insn "*abs2_cconly" [(set (reg CC_REGNUM) - (compare (abs:FPR (match_operand:FPR 1 "register_operand" "f")) - (match_operand:FPR 2 "const0_operand" ""))) - (clobber (match_scratch:FPR 0 "=f"))] - "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "lpbr\t%0,%1" + (compare (abs:BFP (match_operand:BFP 1 "register_operand" "f")) + (match_operand:BFP 2 "const0_operand" ""))) + (clobber (match_scratch:BFP 0 "=f"))] + "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT" + "lpbr\t%0,%1" [(set_attr "op_type" "RRE") (set_attr "type" "fsimp")]) - + +; lpdfr +(define_insn "*abs2_nocc" + [(set (match_operand:FP 0 "register_operand" "=f") + (abs:FP (match_operand:FP 1 "register_operand" "")))] + "TARGET_HARD_FLOAT && TARGET_DFP" + "lpdfr\t%0,%1" + [(set_attr "op_type" "RRE") + (set_attr "type" "fsimp")]) + +; lpxbr, lpdbr, lpebr (define_insn "*abs2" - [(set (match_operand:FPR 0 "register_operand" "=f") - (abs:FPR (match_operand:FPR 1 "register_operand" "f"))) + [(set (match_operand:BFP 0 "register_operand" "=f") + (abs:BFP (match_operand:BFP 1 "register_operand" "f"))) (clobber (reg:CC CC_REGNUM))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "lpbr\t%0,%1" + "TARGET_HARD_FLOAT" + "lpbr\t%0,%1" [(set_attr "op_type" "RRE") (set_attr "type" "fsimp")]) -(define_insn "*abs2_ibm" - [(set (match_operand:FPR 0 "register_operand" "=f") - (abs:FPR (match_operand:FPR 1 "register_operand" "f"))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" - "lpr\t%0,%1" - [(set_attr "op_type" "RR") - (set_attr "type" "fsimp")]) ;; ;;- Negated absolute value instructions @@ -6044,6 +6245,7 @@ "lngfr\t%0,%1" [(set_attr "op_type" "RRE")]) +; lnr, lngr (define_insn "*negabs2_cc" [(set (reg CC_REGNUM) (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d"))) @@ -6053,7 +6255,8 @@ "s390_match_ccmode (insn, CCAmode)" "lnr\t%0,%1" [(set_attr "op_type" "RR")]) - + +; lnr, lngr (define_insn "*negabs2_cconly" [(set (reg CC_REGNUM) (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d"))) @@ -6062,7 +6265,8 @@ "s390_match_ccmode (insn, CCAmode)" "lnr\t%0,%1" [(set_attr "op_type" "RR")]) - + +; lnr, lngr (define_insn "*negabs2" [(set (match_operand:GPR 0 "register_operand" "=d") (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))) @@ -6075,37 +6279,64 @@ ; Floating point ; +; lnxbr, lndbr, lnebr (define_insn "*negabs2_cc" [(set (reg CC_REGNUM) - (compare (neg:FPR (abs:FPR (match_operand:FPR 1 "register_operand" "f"))) - (match_operand:FPR 2 "const0_operand" ""))) - (set (match_operand:FPR 0 "register_operand" "=f") - (neg:FPR (abs:FPR (match_dup 1))))] - "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "lnbr\t%0,%1" + (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f"))) + (match_operand:BFP 2 "const0_operand" ""))) + (set (match_operand:BFP 0 "register_operand" "=f") + (neg:BFP (abs:BFP (match_dup 1))))] + "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT" + "lnbr\t%0,%1" [(set_attr "op_type" "RRE") (set_attr "type" "fsimp")]) - + +; lnxbr, lndbr, lnebr (define_insn "*negabs2_cconly" [(set (reg CC_REGNUM) - (compare (neg:FPR (abs:FPR (match_operand:FPR 1 "register_operand" "f"))) - (match_operand:FPR 2 "const0_operand" ""))) - (clobber (match_scratch:FPR 0 "=f"))] - "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "lnbr\t%0,%1" + (compare (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f"))) + (match_operand:BFP 2 "const0_operand" ""))) + (clobber (match_scratch:BFP 0 "=f"))] + "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT" + "lnbr\t%0,%1" [(set_attr "op_type" "RRE") (set_attr "type" "fsimp")]) - + +; lndfr +(define_insn "*negabs2_nocc" + [(set (match_operand:FP 0 "register_operand" "=f") + (neg:FP (abs:FP (match_operand:BFP 1 "register_operand" ""))))] + "TARGET_HARD_FLOAT && TARGET_DFP" + "lndfr\t%0,%1" + [(set_attr "op_type" "RRE") + (set_attr "type" "fsimp")]) + +; lnxbr, lndbr, lnebr (define_insn "*negabs2" - [(set (match_operand:FPR 0 "register_operand" "=f") - (neg:FPR (abs:FPR (match_operand:FPR 1 "register_operand" "f")))) + [(set (match_operand:BFP 0 "register_operand" "=f") + (neg:BFP (abs:BFP (match_operand:BFP 1 "register_operand" "f")))) (clobber (reg:CC CC_REGNUM))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "lnbr\t%0,%1" + "TARGET_HARD_FLOAT" + "lnbr\t%0,%1" [(set_attr "op_type" "RRE") (set_attr "type" "fsimp")]) ;; +;;- Copy sign instructions +;; + +; cpsdr +(define_insn "copysign3" + [(set (match_operand:FP 0 "register_operand" "=f") + (unspec:FP [(match_operand:FP 1 "register_operand" "") + (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")]) + +;; ;;- Square root instructions. ;; @@ -6113,13 +6344,14 @@ ; sqrt(df|sf)2 instruction pattern(s). ; +; sqxbr, sqdbr, sqebr, sqxb, sqdb, sqeb (define_insn "sqrt2" - [(set (match_operand:FPR 0 "register_operand" "=f,f") - (sqrt:FPR (match_operand:FPR 1 "general_operand" "f,R")))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" + [(set (match_operand:BFP 0 "register_operand" "=f,f") + (sqrt:BFP (match_operand:BFP 1 "general_operand" "f,")))] + "TARGET_HARD_FLOAT" "@ - sqbr\t%0,%1 - sqb\t%0,%1" + sqbr\t%0,%1 + sqb\t%0,%1" [(set_attr "op_type" "RRE,RXE") (set_attr "type" "fsqrt")]) @@ -6160,8 +6392,7 @@ emit_insn (gen_clztidi2 (wide_reg, operands[1], msb)); insn = emit_move_insn (operands[0], gen_highpart (DImode, wide_reg)); - REG_NOTES (insn) = - gen_rtx_EXPR_LIST (REG_EQUAL, clz_equal, REG_NOTES (insn)); + set_unique_reg_note (insn, REG_EQUAL, clz_equal); DONE; }) @@ -6193,6 +6424,7 @@ ; rotl(di|si)3 instruction pattern(s). ; +; rll, rllg (define_insn "rotl3" [(set (match_operand:GPR 0 "register_operand" "=d") (rotate:GPR (match_operand:GPR 1 "register_operand" "d") @@ -6202,6 +6434,7 @@ [(set_attr "op_type" "RSE") (set_attr "atype" "reg")]) +; rll, rllg (define_insn "*rotl3_and" [(set (match_operand:GPR 0 "register_operand" "=d") (rotate:GPR (match_operand:GPR 1 "register_operand" "d") @@ -6228,6 +6461,7 @@ "" "") +; sldl, srdl (define_insn "*di3_31" [(set (match_operand:DI 0 "register_operand" "=d") (SHIFT:DI (match_operand:DI 1 "register_operand" "0") @@ -6237,6 +6471,7 @@ [(set_attr "op_type" "RS") (set_attr "atype" "reg")]) +; sll, srl, sllg, srlg (define_insn "*3" [(set (match_operand:GPR 0 "register_operand" "=d") (SHIFT:GPR (match_operand:GPR 1 "register_operand" "") @@ -6246,6 +6481,7 @@ [(set_attr "op_type" "RS") (set_attr "atype" "reg")]) +; sldl, srdl (define_insn "*di3_31_and" [(set (match_operand:DI 0 "register_operand" "=d") (SHIFT:DI (match_operand:DI 1 "register_operand" "0") @@ -6256,6 +6492,7 @@ [(set_attr "op_type" "RS") (set_attr "atype" "reg")]) +; sll, srl, sllg, srlg (define_insn "*3_and" [(set (match_operand:GPR 0 "register_operand" "=d") (SHIFT:GPR (match_operand:GPR 1 "register_operand" "") @@ -6312,6 +6549,7 @@ [(set_attr "op_type" "RS") (set_attr "atype" "reg")]) +; sra, srag (define_insn "*ashr3_cc" [(set (reg CC_REGNUM) (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "") @@ -6324,6 +6562,7 @@ [(set_attr "op_type" "RS") (set_attr "atype" "reg")]) +; sra, srag (define_insn "*ashr3_cconly" [(set (reg CC_REGNUM) (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "") @@ -6335,6 +6574,7 @@ [(set_attr "op_type" "RS") (set_attr "atype" "reg")]) +; sra, srag (define_insn "*ashr3" [(set (match_operand:GPR 0 "register_operand" "=d") (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "") @@ -6386,6 +6626,7 @@ [(set_attr "op_type" "RS") (set_attr "atype" "reg")]) +; sra, srag (define_insn "*ashr3_cc_and" [(set (reg CC_REGNUM) (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "") @@ -6399,6 +6640,7 @@ [(set_attr "op_type" "RS") (set_attr "atype" "reg")]) +; sra, srag (define_insn "*ashr3_cconly_and" [(set (reg CC_REGNUM) (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "") @@ -6411,6 +6653,7 @@ [(set_attr "op_type" "RS") (set_attr "atype" "reg")]) +; sra, srag (define_insn "*ashr3_and" [(set (match_operand:GPR 0 "register_operand" "=d") (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "") @@ -6621,13 +6864,13 @@ (define_insn_and_split "doloop_si64" [(set (pc) (if_then_else - (ne (match_operand:SI 1 "register_operand" "d,d") + (ne (match_operand:SI 1 "register_operand" "d,d,d") (const_int 1)) (label_ref (match_operand 0 "" "")) (pc))) - (set (match_operand:SI 2 "nonimmediate_operand" "=1,?*m*d") + (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X") (plus:SI (match_dup 1) (const_int -1))) - (clobber (match_scratch:SI 3 "=X,&1")) + (clobber (match_scratch:SI 3 "=X,&1,&?d")) (clobber (reg:CC CC_REGNUM))] "TARGET_CPU_ZARCH" { @@ -6641,7 +6884,8 @@ "&& reload_completed && (! REG_P (operands[2]) || ! rtx_equal_p (operands[1], operands[2]))" - [(parallel [(set (reg:CCAN CC_REGNUM) + [(set (match_dup 3) (match_dup 1)) + (parallel [(set (reg:CCAN CC_REGNUM) (compare:CCAN (plus:SI (match_dup 3) (const_int -1)) (const_int 0))) (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))]) @@ -6659,13 +6903,13 @@ (define_insn_and_split "doloop_si31" [(set (pc) (if_then_else - (ne (match_operand:SI 1 "register_operand" "d,d") + (ne (match_operand:SI 1 "register_operand" "d,d,d") (const_int 1)) (label_ref (match_operand 0 "" "")) (pc))) - (set (match_operand:SI 2 "nonimmediate_operand" "=1,?*m*d") + (set (match_operand:SI 2 "nonimmediate_operand" "=1,?X,?X") (plus:SI (match_dup 1) (const_int -1))) - (clobber (match_scratch:SI 3 "=X,&1")) + (clobber (match_scratch:SI 3 "=X,&1,&?d")) (clobber (reg:CC CC_REGNUM))] "!TARGET_CPU_ZARCH" { @@ -6679,7 +6923,8 @@ "&& reload_completed && (! REG_P (operands[2]) || ! rtx_equal_p (operands[1], operands[2]))" - [(parallel [(set (reg:CCAN CC_REGNUM) + [(set (match_dup 3) (match_dup 1)) + (parallel [(set (reg:CCAN CC_REGNUM) (compare:CCAN (plus:SI (match_dup 3) (const_int -1)) (const_int 0))) (set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))]) @@ -6700,13 +6945,13 @@ (define_insn "*doloop_si_long" [(set (pc) (if_then_else - (ne (match_operand:SI 1 "register_operand" "d,d") + (ne (match_operand:SI 1 "register_operand" "d") (const_int 1)) - (match_operand 0 "address_operand" "U,U") + (match_operand 0 "address_operand" "U") (pc))) - (set (match_operand:SI 2 "register_operand" "=1,?*m*d") + (set (match_operand:SI 2 "register_operand" "=1") (plus:SI (match_dup 1) (const_int -1))) - (clobber (match_scratch:SI 3 "=X,&1")) + (clobber (match_scratch:SI 3 "=X")) (clobber (reg:CC CC_REGNUM))] "!TARGET_CPU_ZARCH" { @@ -6724,13 +6969,13 @@ (define_insn_and_split "doloop_di" [(set (pc) (if_then_else - (ne (match_operand:DI 1 "register_operand" "d,d") + (ne (match_operand:DI 1 "register_operand" "d,d,d") (const_int 1)) (label_ref (match_operand 0 "" "")) (pc))) - (set (match_operand:DI 2 "nonimmediate_operand" "=1,?*m*d") + (set (match_operand:DI 2 "nonimmediate_operand" "=1,?X,?X") (plus:DI (match_dup 1) (const_int -1))) - (clobber (match_scratch:DI 3 "=X,&1")) + (clobber (match_scratch:DI 3 "=X,&1,&?d")) (clobber (reg:CC CC_REGNUM))] "TARGET_64BIT" { @@ -6744,7 +6989,8 @@ "&& reload_completed && (! REG_P (operands[2]) || ! rtx_equal_p (operands[1], operands[2]))" - [(parallel [(set (reg:CCAN CC_REGNUM) + [(set (match_dup 3) (match_dup 1)) + (parallel [(set (reg:CCAN CC_REGNUM) (compare:CCAN (plus:DI (match_dup 3) (const_int -1)) (const_int 0))) (set (match_dup 3) (plus:DI (match_dup 3) (const_int -1)))]) @@ -7300,6 +7546,7 @@ s390_compare_emitted = operands[4]; }) +; cds, cdsg (define_insn "*sync_compare_and_swap" [(set (match_operand:DP 0 "register_operand" "=r") (match_operand:DP 1 "memory_operand" "+Q")) @@ -7316,6 +7563,7 @@ [(set_attr "op_type" "RS") (set_attr "type" "sem")]) +; cs, csg (define_insn "*sync_compare_and_swap" [(set (match_operand:GPR 0 "register_operand" "=r") (match_operand:GPR 1 "memory_operand" "+Q"))