diff options
Diffstat (limited to 'contrib/gcc/config/s390/s390.md')
-rw-r--r-- | contrib/gcc/config/s390/s390.md | 8094 |
1 files changed, 4204 insertions, 3890 deletions
diff --git a/contrib/gcc/config/s390/s390.md b/contrib/gcc/config/s390/s390.md index 345a36a185902..23484098f790f 100644 --- a/contrib/gcc/config/s390/s390.md +++ b/contrib/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 +;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 ;; Free Software Foundation, Inc. ;; Contributed by Hartmut Penner (hpenner@de.ibm.com) and ;; Ulrich Weigand (uweigand@de.ibm.com). @@ -18,53 +18,34 @@ ;; 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, 59 Temple Place - Suite 330, Boston, MA -;; 02111-1307, USA. +;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA +;; 02110-1301, USA. ;; -;; Special constraints for s/390 machine description: -;; -;; a -- Any address register from 1 to 15. -;; d -- Any register from 0 to 15. -;; 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: 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. -;; 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. -;; 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. ;; %D: print opcode suffix for inverse branch condition. ;; %J: print tls_load/tls_gdcall/tls_ldcall suffix +;; %G: print the size of the operand in bytes. ;; %O: print only the displacement of a memory reference. ;; %R: print only the base register of a memory reference. +;; %S: print S-type memory reference (base+displacement). ;; %N: print the second word of a DImode operand. ;; %M: print the second word of a TImode operand. - +;; %Y: print shift count operand. +;; ;; %b: print integer X as if it's an unsigned byte. -;; %x: print integer X as if it's an unsigned word. -;; %h: print integer X as if it's a signed word. -;; %i: print the first nonzero HImode part of X -;; %j: print the first HImode part unequal to 0xffff of X - +;; %x: print integer X as if it's an unsigned halfword. +;; %h: print integer X as if it's a signed halfword. +;; %i: print the first nonzero HImode part of X. +;; %j: print the first HImode part unequal to -1 of X. +;; %k: print the first nonzero SImode part of X. +;; %m: print the first SImode part unequal to -1 of X. +;; %o: print integer X as if it's an unsigned 32bit word. ;; ;; We have a special constraint for pattern matching. ;; @@ -78,7 +59,8 @@ (define_constants [; Miscellaneous (UNSPEC_ROUND 1) - (UNSPEC_SETHIGH 10) + (UNSPEC_CMPINT 2) + (UNSPEC_ICM 10) ; GOT/PLT and lt-relative accesses (UNSPEC_LTREL_OFFSET 100) @@ -92,6 +74,9 @@ ; Literal pool (UNSPEC_RELOAD_BASE 210) (UNSPEC_MAIN_BASE 211) + (UNSPEC_LTREF 212) + (UNSPEC_INSN 213) + (UNSPEC_EXECUTE 214) ; TLS relocation specifiers (UNSPEC_TLSGD 500) @@ -102,12 +87,16 @@ (UNSPEC_INDNTPOFF 505) ; TLS support - (UNSPEC_TP 510) (UNSPEC_TLSLDM_NTPOFF 511) (UNSPEC_TLS_LOAD 512) ; String Functions - (UNSPEC_SRST 600) + (UNSPEC_SRST 600) + (UNSPEC_MVST 601) + + ; Stack Smashing Protector + (UNSPEC_SP_SET 700) + (UNSPEC_SP_TEST 701) ]) ;; @@ -118,233 +107,241 @@ [; Blockage (UNSPECV_BLOCKAGE 0) + ; TPF Support + (UNSPECV_TPF_PROLOGUE 20) + (UNSPECV_TPF_EPILOGUE 21) + ; Literal pool (UNSPECV_POOL 200) - (UNSPECV_POOL_START 201) - (UNSPECV_POOL_END 202) + (UNSPECV_POOL_SECTION 201) + (UNSPECV_POOL_ALIGN 202) (UNSPECV_POOL_ENTRY 203) (UNSPECV_MAIN_POOL 300) ; TLS support (UNSPECV_SET_TP 500) - ]) - -;; Processor type. This attribute must exactly match the processor_type -;; enumeration in s390.h. + ; Atomic Support + (UNSPECV_MB 700) + (UNSPECV_CAS 701) + ]) -(define_attr "cpu" "g5,g6,z900,z990" - (const (symbol_ref "s390_tune"))) +;; +;; Registers +;; -;; Define an insn type attribute. This is used in function unit delay -;; computations. +(define_constants + [ + ; Sibling call register. + (SIBCALL_REGNUM 1) + ; Literal pool base register. + (BASE_REGNUM 13) + ; Return address register. + (RETURN_REGNUM 14) + ; Condition code register. + (CC_REGNUM 33) + ; Thread local storage pointer register. + (TP_REGNUM 36) + ]) -(define_attr "type" "none,integer,load,lr,la,larl,lm,stm, - cs,vs,store,imul,idiv, - branch,jsr,fsimpd,fsimps, - floadd,floads,fstored, fstores, - fmuld,fmuls,fdivd,fdivs, - ftoi,itof,fsqrtd,fsqrts, - other,o2,o3" - (const_string "integer")) -;; Operand type. Used to default length attribute values +;; 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" - (const_string "RX")) + (const_string "NN")) -;; Insn are devide in two classes: -;; agen: Insn using agen -;; reg: Insn not using agen +;; Instruction type attribute used for scheduling. + +(define_attr "type" "none,integer,load,lr,la,larl,lm,stm, + cs,vs,store,sem,idiv, + imulhi,imulsi,imuldi, + 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"))) + +;; Another attribute used for scheduling purposes: +;; agen: Instruction uses the address generation unit +;; reg: Instruction does not use the agen unit (define_attr "atype" "agen,reg" -(cond [ (eq_attr "op_type" "E") (const_string "reg") - (eq_attr "op_type" "RR") (const_string "reg") - (eq_attr "op_type" "RX") (const_string "agen") - (eq_attr "op_type" "RI") (const_string "reg") - (eq_attr "op_type" "RRE") (const_string "reg") - (eq_attr "op_type" "RS") (const_string "agen") - (eq_attr "op_type" "RSI") (const_string "agen") - (eq_attr "op_type" "S") (const_string "agen") - (eq_attr "op_type" "SI") (const_string "agen") - (eq_attr "op_type" "SS") (const_string "agen") - (eq_attr "op_type" "SSE") (const_string "agen") - (eq_attr "op_type" "RXE") (const_string "agen") - (eq_attr "op_type" "RSE") (const_string "agen") - (eq_attr "op_type" "RIL") (const_string "agen") - (eq_attr "op_type" "RXY") (const_string "agen") - (eq_attr "op_type" "RSY") (const_string "agen") - (eq_attr "op_type" "SIY") (const_string "agen")] - (const_string "reg"))) + (if_then_else (eq_attr "op_type" "E,RR,RI,RRE") + (const_string "reg") + (const_string "agen"))) -;; Generic pipeline function unit. +;; Length in bytes. -(define_function_unit "integer" 1 0 - (eq_attr "type" "none") 0 0) +(define_attr "length" "" + (cond [(eq_attr "op_type" "E,RR") (const_int 2) + (eq_attr "op_type" "RX,RI,RRE,RS,RSI,S,SI") (const_int 4)] + (const_int 6))) -(define_function_unit "integer" 1 0 - (eq_attr "type" "integer") 1 1) -(define_function_unit "integer" 1 0 - (eq_attr "type" "fsimpd") 1 1) +;; Processor type. This attribute must exactly match the processor_type +;; enumeration in s390.h. The current machine description does not +;; distinguish between g5 and g6, but there are differences between the two +;; CPUs could in theory be modeled. -(define_function_unit "integer" 1 0 - (eq_attr "type" "fsimps") 1 1) +(define_attr "cpu" "g5,g6,z900,z990,z9_109" + (const (symbol_ref "s390_tune"))) -(define_function_unit "integer" 1 0 - (eq_attr "type" "load") 1 1) +;; Pipeline description for z900. For lack of anything better, +;; this description is also used for the g5 and g6. +(include "2064.md") -(define_function_unit "integer" 1 0 - (eq_attr "type" "floadd") 1 1) +;; Pipeline description for z990. +(include "2084.md") -(define_function_unit "integer" 1 0 - (eq_attr "type" "floads") 1 1) +;; Predicates +(include "predicates.md") -(define_function_unit "integer" 1 0 - (eq_attr "type" "la") 1 1) +;; Constraint definitions +(include "constraints.md") -(define_function_unit "integer" 1 0 - (eq_attr "type" "larl") 1 1) +;; Other includes +(include "tpf.md") -(define_function_unit "integer" 1 0 - (eq_attr "type" "lr") 1 1) +;; Macros -(define_function_unit "integer" 1 0 - (eq_attr "type" "branch") 1 1) +;; This mode macro allows floating point patterns to be generated from the +;; same template. +(define_mode_macro FPR [TF DF SF]) +(define_mode_macro DSF [DF SF]) -(define_function_unit "integer" 1 0 - (eq_attr "type" "store") 1 1) +;; These mode macros allow 31-bit and 64-bit TDSI patterns to be generated +;; from the same template. +(define_mode_macro TDSI [(TI "TARGET_64BIT") DI SI]) -(define_function_unit "integer" 1 0 - (eq_attr "type" "fstored") 1 1) +;; These mode macros 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_function_unit "integer" 1 0 - (eq_attr "type" "fstores") 1 1) +;; This mode macro allows :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_function_unit "integer" 1 0 - (eq_attr "type" "lm") 2 2) +;; This mode macro allows the QI and HI patterns to be defined from +;; the same template. +(define_mode_macro HQI [HI QI]) -(define_function_unit "integer" 1 0 - (eq_attr "type" "stm") 2 2) +;; This mode macro allows the integer patterns to be defined from the +;; same template. +(define_mode_macro INT [(DI "TARGET_64BIT") SI HI QI]) -(define_function_unit "integer" 1 0 - (eq_attr "type" "cs") 5 5) +;; This macro allows to unify all 'bCOND' expander patterns. +(define_code_macro COMPARE [eq ne gt gtu lt ltu ge geu le leu unordered + ordered uneq unlt ungt unle unge ltgt]) -(define_function_unit "integer" 1 0 - (eq_attr "type" "vs") 30 30) +;; This macro allows to unify all 'sCOND' patterns. +(define_code_macro SCOND [ltu gtu leu geu]) -(define_function_unit "integer" 1 0 - (eq_attr "type" "jsr") 5 5) +;; This macro allows some 'ashift' and 'lshiftrt' pattern to be defined from +;; the same template. +(define_code_macro SHIFT [ashift lshiftrt]) -(define_function_unit "integer" 1 0 - (eq_attr "type" "imul") 7 7) +;; These macros allow to combine most atomic operations. +(define_code_macro ATOMIC [and ior xor plus minus mult]) +(define_code_attr atomic [(and "and") (ior "ior") (xor "xor") + (plus "add") (minus "sub") (mult "nand")]) -(define_function_unit "integer" 1 0 - (eq_attr "type" "fmuld") 6 6) -(define_function_unit "integer" 1 0 - (eq_attr "type" "fmuls") 6 6) +;; In FPR templates, a string like "lt<de>br" will expand to "ltxbr" in TFmode, +;; "ltdbr" in DFmode, and "ltebr" in SFmode. +(define_mode_attr xde [(TF "x") (DF "d") (SF "e")]) -(define_function_unit "integer" 1 0 - (eq_attr "type" "idiv") 33 33) +;; In FPR templates, a string like "m<dee>br" will expand to "mxbr" in TFmode, +;; "mdbr" in DFmode, and "meebr" in SFmode. +(define_mode_attr xdee [(TF "x") (DF "d") (SF "ee")]) -(define_function_unit "integer" 1 0 - (eq_attr "type" "fdivd") 33 33) +;; In FPR templates, "<RRe>" will expand to "RRE" in TFmode and "RR" otherwise. +;; Likewise for "<RXe>". +(define_mode_attr RRe [(TF "RRE") (DF "RR") (SF "RR")]) +(define_mode_attr RXe [(TF "RXE") (DF "RX") (SF "RX")]) -(define_function_unit "integer" 1 0 - (eq_attr "type" "fdivs") 33 33) +;; In FPR templates, "<Rf>" will expand to "f" in TFmode and "R" otherwise. +;; This is used to disable the memory alternative in TFmode patterns. +(define_mode_attr Rf [(TF "f") (DF "R") (SF "R")]) -(define_function_unit "integer" 1 0 - (eq_attr "type" "fsqrtd") 30 30) +;; In GPR and P templates, a constraint like "<d0>" will expand to "d" in DImode +;; and "0" in SImode. This allows to combine instructions of which the 31bit +;; version only operates on one register. +(define_mode_attr d0 [(DI "d") (SI "0")]) -(define_function_unit "integer" 1 0 - (eq_attr "type" "fsqrts") 30 30) +;; In combination with d0 this allows to combine instructions of which the 31bit +;; version only operates on one register. The DImode version needs an additional +;; register for the assembler output. +(define_mode_attr 1 [(DI "%1,") (SI "")]) + +;; In SHIFT templates, a string like "s<lr>dl" will expand to "sldl" in +;; 'ashift' and "srdl" in 'lshiftrt'. +(define_code_attr lr [(ashift "l") (lshiftrt "r")]) -(define_function_unit "integer" 1 0 - (eq_attr "type" "ftoi") 2 2) +;; In SHIFT templates, this attribute holds the correct standard name for the +;; pattern itself and the corresponding function calls. +(define_code_attr shift [(ashift "ashl") (lshiftrt "lshr")]) -(define_function_unit "integer" 1 0 - (eq_attr "type" "itof") 2 2) +;; This attribute handles differences in the instruction 'type' and will result +;; in "RRE" for DImode and "RR" for SImode. +(define_mode_attr E [(DI "E") (SI "")]) -(define_function_unit "integer" 1 0 - (eq_attr "type" "o2") 2 2) +;; This attribute handles differences in the instruction 'type' and makes RX<Y> +;; to result in "RXY" for DImode and "RX" for SImode. +(define_mode_attr Y [(DI "Y") (SI "")]) -(define_function_unit "integer" 1 0 - (eq_attr "type" "o3") 3 3) +;; 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 "")]) -(define_function_unit "integer" 1 0 - (eq_attr "type" "other") 5 5) +;; In GPR templates, a string like "lc<g>r" will expand to "lcgr" in DImode +;; and "lcr" in SImode. +(define_mode_attr g [(DI "g") (SI "")]) -;; Pipeline description for z900 +;; In GPR templates, a string like "sl<y>" 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")]) -(include "2064.md") -(include "2084.md") +;; In DP templates, a string like "cds<g>" will expand to "cdsg" in TImode +;; and "cds" in DImode. +(define_mode_attr tg [(TI "g") (DI "")]) -;; Length in bytes. +;; In GPR templates, a string like "c<gf>dbr" will expand to "cgdbr" in DImode +;; and "cfdbr" in SImode. +(define_mode_attr gf [(DI "g") (SI "f")]) -(define_attr "length" "" -(cond [ (eq_attr "op_type" "E") (const_int 2) - (eq_attr "op_type" "RR") (const_int 2) - (eq_attr "op_type" "RX") (const_int 4) - (eq_attr "op_type" "RI") (const_int 4) - (eq_attr "op_type" "RRE") (const_int 4) - (eq_attr "op_type" "RS") (const_int 4) - (eq_attr "op_type" "RSI") (const_int 4) - (eq_attr "op_type" "S") (const_int 4) - (eq_attr "op_type" "SI") (const_int 4) - (eq_attr "op_type" "SS") (const_int 6) - (eq_attr "op_type" "SSE") (const_int 6) - (eq_attr "op_type" "RXE") (const_int 6) - (eq_attr "op_type" "RSE") (const_int 6) - (eq_attr "op_type" "RIL") (const_int 6) - (eq_attr "op_type" "RXY") (const_int 6) - (eq_attr "op_type" "RSY") (const_int 6) - (eq_attr "op_type" "SIY") (const_int 6)] - (const_int 4))) - -;; Define attributes for `asm' insns. - -(define_asm_attributes [(set_attr "type" "other") - (set_attr "op_type" "NN")]) +;; ICM mask required to load MODE value into the lowest subreg +;; of a SImode register. +(define_mode_attr icm_lo [(HI "3") (QI "1")]) -;; -;; Condition Codes -;; -; -; CCL: Zero Nonzero Zero Nonzero (AL, ALR, SL, SLR, N, NC, NI, NR, O, OC, OI, OR, X, XC, XI, XR) -; CCA: Zero <Zero >Zero Overflow (A, AR, AH, AHI, S, SR, SH, SHI, LTR, LCR, LNR, LPR, SLA, SLDA, SLA, SRDA) -; CCU: Equal ULess UGreater -- (CL, CLR, CLI, CLM) -; CCS: Equal SLess SGreater -- (C, CR, CH, CHI, ICM) -; CCT: Zero Mixed Mixed Ones (TM, TMH, TML) +;; In HQI templates, a string like "llg<hc>" will expand to "llgh" in +;; HImode and "llgc" in QImode. +(define_mode_attr hc [(HI "h") (QI "c")]) -; CCZ -> CCL / CCZ1 -; CCZ1 -> CCA/CCU/CCS/CCT -; CCS -> CCA +;; In P templates, the mode <DBL> will expand to "TI" in DImode and "DI" +;; in SImode. +(define_mode_attr DBL [(DI "TI") (SI "DI")]) -; String: CLC, CLCL, CLCLE, CLST, CUSE, MVCL, MVCLE, MVPG, MVST, SRST -; Clobber: CKSM, CFC, CS, CDS, CUUTF, CUTFU, PLO, SPM, STCK, STCKE, TS, TRT, TRE, UPT +;; Maximum unsigned integer that fits in MODE. +(define_mode_attr max_uint [(HI "65535") (QI "255")]) ;; ;;- Compare instructions. ;; -(define_expand "cmpdi" - [(set (reg:CC 33) - (compare:CC (match_operand:DI 0 "register_operand" "") - (match_operand:DI 1 "general_operand" "")))] - "TARGET_64BIT" -{ - s390_compare_op0 = operands[0]; - s390_compare_op1 = operands[1]; - DONE; -}) - -(define_expand "cmpsi" - [(set (reg:CC 33) - (compare:CC (match_operand:SI 0 "register_operand" "") - (match_operand:SI 1 "general_operand" "")))] +(define_expand "cmp<mode>" + [(set (reg:CC CC_REGNUM) + (compare:CC (match_operand:GPR 0 "register_operand" "") + (match_operand:GPR 1 "general_operand" "")))] "" { s390_compare_op0 = operands[0]; @@ -352,10 +349,10 @@ DONE; }) -(define_expand "cmpdf" - [(set (reg:CC 33) - (compare:CC (match_operand:DF 0 "register_operand" "") - (match_operand:DF 1 "general_operand" "")))] +(define_expand "cmp<mode>" + [(set (reg:CC CC_REGNUM) + (compare:CC (match_operand:FPR 0 "register_operand" "") + (match_operand:FPR 1 "general_operand" "")))] "TARGET_HARD_FLOAT" { s390_compare_op0 = operands[0]; @@ -363,185 +360,28 @@ DONE; }) -(define_expand "cmpsf" - [(set (reg:CC 33) - (compare:CC (match_operand:SF 0 "register_operand" "") - (match_operand:SF 1 "general_operand" "")))] - "TARGET_HARD_FLOAT" -{ - s390_compare_op0 = operands[0]; - s390_compare_op1 = operands[1]; - DONE; -}) - - -; Test-under-Mask (zero_extract) instructions - -(define_insn "*tmdi_ext" - [(set (reg 33) - (compare (zero_extract:DI (match_operand:DI 0 "register_operand" "d") - (match_operand:DI 1 "const_int_operand" "n") - (match_operand:DI 2 "const_int_operand" "n")) - (const_int 0)))] - "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT - && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0 - && INTVAL (operands[1]) + INTVAL (operands[2]) <= 64 - && (INTVAL (operands[1]) + INTVAL (operands[2]) - 1) >> 4 - == INTVAL (operands[2]) >> 4" -{ - int part = INTVAL (operands[2]) >> 4; - int block = (1 << INTVAL (operands[1])) - 1; - int shift = 16 - INTVAL (operands[1]) - (INTVAL (operands[2]) & 15); - - operands[2] = GEN_INT (block << shift); - - switch (part) - { - case 0: return "tmhh\t%0,%x2"; - case 1: return "tmhl\t%0,%x2"; - case 2: return "tmlh\t%0,%x2"; - case 3: return "tmll\t%0,%x2"; - default: abort (); - } -} - [(set_attr "op_type" "RI")]) - -(define_insn "*tmsi_ext" - [(set (reg 33) - (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "d") - (match_operand:SI 1 "const_int_operand" "n") - (match_operand:SI 2 "const_int_operand" "n")) - (const_int 0)))] - "s390_match_ccmode(insn, CCTmode) - && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0 - && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32 - && (INTVAL (operands[1]) + INTVAL (operands[2]) - 1) >> 4 - == INTVAL (operands[2]) >> 4" -{ - int part = INTVAL (operands[2]) >> 4; - int block = (1 << INTVAL (operands[1])) - 1; - int shift = 16 - INTVAL (operands[1]) - (INTVAL (operands[2]) & 15); - - operands[2] = GEN_INT (block << shift); - - switch (part) - { - case 0: return "tmh\t%0,%x2"; - case 1: return "tml\t%0,%x2"; - default: abort (); - } -} - [(set_attr "op_type" "RI")]) - -(define_insn "*tmqisi_ext" - [(set (reg 33) - (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "Q,S") - (match_operand:SI 1 "const_int_operand" "n,n") - (match_operand:SI 2 "const_int_operand" "n,n")) - (const_int 0)))] - "!TARGET_64BIT && s390_match_ccmode(insn, CCTmode) - && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0 - && INTVAL (operands[1]) + INTVAL (operands[2]) <= 8" -{ - int block = (1 << INTVAL (operands[1])) - 1; - int shift = 8 - INTVAL (operands[1]) - INTVAL (operands[2]); - - operands[2] = GEN_INT (block << shift); - return which_alternative == 0 ? "tm\t%0,%b2" : "tmy\t%0,%b2"; -} - [(set_attr "op_type" "SI,SIY")]) - -(define_insn "*tmqidi_ext" - [(set (reg 33) - (compare (zero_extract:DI (match_operand:QI 0 "memory_operand" "Q,S") - (match_operand:SI 1 "const_int_operand" "n,n") - (match_operand:SI 2 "const_int_operand" "n,n")) - (const_int 0)))] - "TARGET_64BIT && s390_match_ccmode(insn, CCTmode) - && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0 - && INTVAL (operands[1]) + INTVAL (operands[2]) <= 8" -{ - int block = (1 << INTVAL (operands[1])) - 1; - int shift = 8 - INTVAL (operands[1]) - INTVAL (operands[2]); - - operands[2] = GEN_INT (block << shift); - return which_alternative == 0 ? "tm\t%0,%b2" : "tmy\t%0,%b2"; -} - [(set_attr "op_type" "SI,SIY")]) - ; Test-under-Mask instructions -(define_insn "*tmdi_mem" - [(set (reg 33) - (compare (and:DI (match_operand:DI 0 "memory_operand" "Q,S") - (match_operand:DI 1 "immediate_operand" "n,n")) - (match_operand:DI 2 "immediate_operand" "n,n")))] - "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0)) - && s390_single_part (operands[1], DImode, QImode, 0) >= 0" -{ - int part = s390_single_part (operands[1], DImode, QImode, 0); - operands[1] = GEN_INT (s390_extract_part (operands[1], QImode, 0)); - - operands[0] = gen_rtx_MEM (QImode, - plus_constant (XEXP (operands[0], 0), part)); - return which_alternative == 0 ? "tm\t%0,%b1" : "tmy\t%0,%b1"; -} - [(set_attr "op_type" "SI,SIY")]) - -(define_insn "*tmsi_mem" - [(set (reg 33) - (compare (and:SI (match_operand:SI 0 "memory_operand" "Q,S") - (match_operand:SI 1 "immediate_operand" "n,n")) - (match_operand:SI 2 "immediate_operand" "n,n")))] - "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0)) - && s390_single_part (operands[1], SImode, QImode, 0) >= 0" -{ - int part = s390_single_part (operands[1], SImode, QImode, 0); - operands[1] = GEN_INT (s390_extract_part (operands[1], QImode, 0)); - - operands[0] = gen_rtx_MEM (QImode, - plus_constant (XEXP (operands[0], 0), part)); - return which_alternative == 0 ? "tm\t%0,%b1" : "tmy\t%0,%b1"; -} - [(set_attr "op_type" "SI")]) - -(define_insn "*tmhi_mem" - [(set (reg 33) - (compare (and:SI (subreg:SI (match_operand:HI 0 "memory_operand" "Q,S") 0) - (match_operand:SI 1 "immediate_operand" "n,n")) - (match_operand:SI 2 "immediate_operand" "n,n")))] - "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0)) - && s390_single_part (operands[1], HImode, QImode, 0) >= 0" -{ - int part = s390_single_part (operands[1], HImode, QImode, 0); - operands[1] = GEN_INT (s390_extract_part (operands[1], QImode, 0)); - - operands[0] = gen_rtx_MEM (QImode, - plus_constant (XEXP (operands[0], 0), part)); - return which_alternative == 0 ? "tm\t%0,%b1" : "tmy\t%0,%b1"; -} - [(set_attr "op_type" "SI")]) - (define_insn "*tmqi_mem" - [(set (reg 33) - (compare (and:SI (subreg:SI (match_operand:QI 0 "memory_operand" "Q,S") 0) - (match_operand:SI 1 "immediate_operand" "n,n")) - (match_operand:SI 2 "immediate_operand" "n,n")))] - "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))" - "@ - tm\t%0,%b1 - tmy\t%0,%b1" + [(set (reg CC_REGNUM) + (compare (and:QI (match_operand:QI 0 "memory_operand" "Q,S") + (match_operand:QI 1 "immediate_operand" "n,n")) + (match_operand:QI 2 "immediate_operand" "n,n")))] + "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], false))" + "@ + tm\t%S0,%b1 + tmy\t%S0,%b1" [(set_attr "op_type" "SI,SIY")]) (define_insn "*tmdi_reg" - [(set (reg 33) + [(set (reg CC_REGNUM) (compare (and:DI (match_operand:DI 0 "nonimmediate_operand" "d,d,d,d") - (match_operand:DI 1 "immediate_operand" + (match_operand:DI 1 "immediate_operand" "N0HD0,N1HD0,N2HD0,N3HD0")) (match_operand:DI 2 "immediate_operand" "n,n,n,n")))] "TARGET_64BIT - && s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 1)) + && s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true)) && s390_single_part (operands[1], DImode, HImode, 0) >= 0" "@ tmhh\t%0,%i1 @@ -551,38 +391,34 @@ [(set_attr "op_type" "RI")]) (define_insn "*tmsi_reg" - [(set (reg 33) + [(set (reg CC_REGNUM) (compare (and:SI (match_operand:SI 0 "nonimmediate_operand" "d,d") (match_operand:SI 1 "immediate_operand" "N0HS0,N1HS0")) (match_operand:SI 2 "immediate_operand" "n,n")))] - "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 1)) + "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], true)) && s390_single_part (operands[1], SImode, HImode, 0) >= 0" "@ tmh\t%0,%i1 tml\t%0,%i1" [(set_attr "op_type" "RI")]) -(define_insn "*tmhi_full" - [(set (reg 33) - (compare (match_operand:HI 0 "register_operand" "d") - (match_operand:HI 1 "immediate_operand" "n")))] - "s390_match_ccmode (insn, s390_tm_ccmode (GEN_INT (-1), operands[1], 1))" - "tml\t%0,65535" - [(set_attr "op_type" "RX")]) - -(define_insn "*tmqi_full" - [(set (reg 33) - (compare (match_operand:QI 0 "register_operand" "d") - (match_operand:QI 1 "immediate_operand" "n")))] - "s390_match_ccmode (insn, s390_tm_ccmode (GEN_INT (-1), operands[1], 1))" - "tml\t%0,255" +(define_insn "*tm<mode>_full" + [(set (reg CC_REGNUM) + (compare (match_operand:HQI 0 "register_operand" "d") + (match_operand:HQI 1 "immediate_operand" "n")))] + "s390_match_ccmode (insn, s390_tm_ccmode (constm1_rtx, operands[1], true))" + "tml\t%0,<max_uint>" [(set_attr "op_type" "RI")]) +; ; Load-and-Test instructions +; + +; tst(di|si) instruction pattern(s). (define_insn "*tstdi_sign" - [(set (reg 33) + [(set (reg CC_REGNUM) (compare (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 0 "register_operand" "d") 0) (const_int 32)) (const_int 32)) (match_operand:DI 1 "const0_operand" ""))) @@ -592,167 +428,180 @@ "ltgfr\t%2,%0" [(set_attr "op_type" "RRE")]) +; ltr, lt, ltgr, ltg +(define_insn "*tst<mode>_extimm" + [(set (reg CC_REGNUM) + (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_EXTIMM" + "@ + lt<g>r\t%2,%0 + lt<g>\t%2,%0" + [(set_attr "op_type" "RR<E>,RXY")]) + +; ltr, lt, ltgr, ltg +(define_insn "*tst<mode>_cconly_extimm" + [(set (reg CC_REGNUM) + (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" + "@ + lt<g>r\t%0,%0 + lt<g>\t%2,%0" + [(set_attr "op_type" "RR<E>,RXY")]) + (define_insn "*tstdi" - [(set (reg 33) + [(set (reg CC_REGNUM) (compare (match_operand:DI 0 "register_operand" "d") (match_operand:DI 1 "const0_operand" ""))) (set (match_operand:DI 2 "register_operand" "=d") (match_dup 0))] - "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT" + "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT && !TARGET_EXTIMM" "ltgr\t%2,%0" [(set_attr "op_type" "RRE")]) -(define_insn "*tstdi_cconly" - [(set (reg 33) - (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 33) - (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" - [(set (reg 33) + [(set (reg CC_REGNUM) (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S") (match_operand:SI 1 "const0_operand" ""))) (set (match_operand:SI 2 "register_operand" "=d,d,d") (match_dup 0))] - "s390_match_ccmode(insn, CCSmode)" + "s390_match_ccmode(insn, CCSmode) && !TARGET_EXTIMM" "@ ltr\t%2,%0 - icm\t%2,15,%0 - icmy\t%2,15,%0" + icm\t%2,15,%S0 + icmy\t%2,15,%S0" [(set_attr "op_type" "RR,RS,RSY")]) (define_insn "*tstsi_cconly" - [(set (reg 33) + [(set (reg CC_REGNUM) (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q,S") (match_operand:SI 1 "const0_operand" ""))) (clobber (match_scratch:SI 2 "=X,d,d"))] "s390_match_ccmode(insn, CCSmode)" "@ ltr\t%0,%0 - icm\t%2,15,%0 - icmy\t%2,15,%0" + icm\t%2,15,%S0 + icmy\t%2,15,%S0" [(set_attr "op_type" "RR,RS,RSY")]) -(define_insn "*tstsi_cconly2" - [(set (reg 33) - (compare (match_operand:SI 0 "register_operand" "d") - (match_operand:SI 1 "const0_operand" "")))] +(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<mode>_cconly2" + [(set (reg CC_REGNUM) + (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")]) + "lt<g>r\t%0,%0" + [(set_attr "op_type" "RR<E>")]) -(define_insn "*tsthiCCT" - [(set (reg 33) - (compare (match_operand:HI 0 "nonimmediate_operand" "?Q,?S,d") - (match_operand:HI 1 "const0_operand" ""))) - (set (match_operand:HI 2 "register_operand" "=d,d,0") +; tst(hi|qi) instruction pattern(s). + +(define_insn "*tst<mode>CCT" + [(set (reg CC_REGNUM) + (compare (match_operand:HQI 0 "nonimmediate_operand" "?Q,?S,d") + (match_operand:HQI 1 "const0_operand" ""))) + (set (match_operand:HQI 2 "register_operand" "=d,d,0") (match_dup 0))] "s390_match_ccmode(insn, CCTmode)" "@ - icm\t%2,3,%0 - icmy\t%2,3,%0 - tml\t%0,65535" + icm\t%2,<icm_lo>,%S0 + icmy\t%2,<icm_lo>,%S0 + tml\t%0,<max_uint>" [(set_attr "op_type" "RS,RSY,RI")]) (define_insn "*tsthiCCT_cconly" - [(set (reg 33) + [(set (reg CC_REGNUM) (compare (match_operand:HI 0 "nonimmediate_operand" "Q,S,d") (match_operand:HI 1 "const0_operand" ""))) (clobber (match_scratch:HI 2 "=d,d,X"))] "s390_match_ccmode(insn, CCTmode)" "@ - icm\t%2,3,%0 - icmy\t%2,3,%0 + icm\t%2,3,%S0 + icmy\t%2,3,%S0 tml\t%0,65535" [(set_attr "op_type" "RS,RSY,RI")]) -(define_insn "*tsthi" - [(set (reg 33) - (compare (match_operand:HI 0 "s_operand" "Q,S") - (match_operand:HI 1 "const0_operand" ""))) - (set (match_operand:HI 2 "register_operand" "=d,d") - (match_dup 0))] - "s390_match_ccmode(insn, CCSmode)" - "@ - icm\t%2,3,%0 - icmy\t%2,3,%0" - [(set_attr "op_type" "RS,RSY")]) - -(define_insn "*tsthi_cconly" - [(set (reg 33) - (compare (match_operand:HI 0 "s_operand" "Q,S") - (match_operand:HI 1 "const0_operand" ""))) - (clobber (match_scratch:HI 2 "=d,d"))] - "s390_match_ccmode(insn, CCSmode)" - "@ - icm\t%2,3,%0 - icmy\t%2,3,%0" - [(set_attr "op_type" "RS,RSY")]) - -(define_insn "*tstqiCCT" - [(set (reg 33) - (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,?S,d") - (match_operand:QI 1 "const0_operand" ""))) - (set (match_operand:QI 2 "register_operand" "=d,d,0") - (match_dup 0))] - "s390_match_ccmode(insn, CCTmode)" - "@ - icm\t%2,1,%0 - icmy\t%2,1,%0 - tml\t%0,255" - [(set_attr "op_type" "RS,RSY,RI")]) - (define_insn "*tstqiCCT_cconly" - [(set (reg 33) + [(set (reg CC_REGNUM) (compare (match_operand:QI 0 "nonimmediate_operand" "?Q,?S,d") (match_operand:QI 1 "const0_operand" "")))] "s390_match_ccmode(insn, CCTmode)" "@ - cli\t%0,0 - cliy\t%0,0 + cli\t%S0,0 + cliy\t%S0,0 tml\t%0,255" [(set_attr "op_type" "SI,SIY,RI")]) -(define_insn "*tstqi" - [(set (reg 33) - (compare (match_operand:QI 0 "s_operand" "Q,S") - (match_operand:QI 1 "const0_operand" ""))) - (set (match_operand:QI 2 "register_operand" "=d,d") +(define_insn "*tst<mode>" + [(set (reg CC_REGNUM) + (compare (match_operand:HQI 0 "s_operand" "Q,S") + (match_operand:HQI 1 "const0_operand" ""))) + (set (match_operand:HQI 2 "register_operand" "=d,d") (match_dup 0))] "s390_match_ccmode(insn, CCSmode)" "@ - icm\t%2,1,%0 - icmy\t%2,1,%0" + icm\t%2,<icm_lo>,%S0 + icmy\t%2,<icm_lo>,%S0" [(set_attr "op_type" "RS,RSY")]) -(define_insn "*tstqi_cconly" - [(set (reg 33) - (compare (match_operand:QI 0 "s_operand" "Q,S") - (match_operand:QI 1 "const0_operand" ""))) - (clobber (match_scratch:QI 2 "=d,d"))] +(define_insn "*tst<mode>_cconly" + [(set (reg CC_REGNUM) + (compare (match_operand:HQI 0 "s_operand" "Q,S") + (match_operand:HQI 1 "const0_operand" ""))) + (clobber (match_scratch:HQI 2 "=d,d"))] "s390_match_ccmode(insn, CCSmode)" "@ - icm\t%2,1,%0 - icmy\t%2,1,%0" + icm\t%2,<icm_lo>,%S0 + icmy\t%2,<icm_lo>,%S0" [(set_attr "op_type" "RS,RSY")]) +; Compare (equality) instructions + +(define_insn "*cmpdi_cct" + [(set (reg CC_REGNUM) + (compare (match_operand:DI 0 "nonimmediate_operand" "%d,d,d,d,Q") + (match_operand:DI 1 "general_operand" "d,K,Os,m,BQ")))] + "s390_match_ccmode (insn, CCTmode) && 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,SS")]) + +(define_insn "*cmpsi_cct" + [(set (reg CC_REGNUM) + (compare (match_operand:SI 0 "nonimmediate_operand" "%d,d,d,d,d,Q") + (match_operand:SI 1 "general_operand" "d,K,Os,R,T,BQ")))] + "s390_match_ccmode (insn, CCTmode)" + "@ + 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,SS")]) + + ; Compare (signed) instructions (define_insn "*cmpdi_ccs_sign" - [(set (reg 33) + [(set (reg CC_REGNUM) (compare (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m")) (match_operand:DI 0 "register_operand" "d,d")))] "s390_match_ccmode(insn, CCSRmode) && TARGET_64BIT" @@ -761,19 +610,8 @@ cgf\t%0,%1" [(set_attr "op_type" "RRE,RXY")]) -(define_insn "*cmpdi_ccs" - [(set (reg 33) - (compare (match_operand:DI 0 "register_operand" "d,d,d") - (match_operand:DI 1 "general_operand" "d,K,m")))] - "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT" - "@ - cgr\t%0,%1 - cghi\t%0,%c1 - cg\t%0,%1" - [(set_attr "op_type" "RRE,RI,RXY")]) - (define_insn "*cmpsi_ccs_sign" - [(set (reg 33) + [(set (reg CC_REGNUM) (compare (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T")) (match_operand:SI 0 "register_operand" "d,d")))] "s390_match_ccmode(insn, CCSRmode)" @@ -782,199 +620,168 @@ chy\t%0,%1" [(set_attr "op_type" "RX,RXY")]) -(define_insn "*cmpsi_ccs" - [(set (reg 33) - (compare (match_operand:SI 0 "register_operand" "d,d,d,d") - (match_operand:SI 1 "general_operand" "d,K,R,T")))] +; cr, chi, cfi, c, cy, cgr, cghi, cgfi, cg +(define_insn "*cmp<mode>_ccs" + [(set (reg CC_REGNUM) + (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,%c1 - c\t%0,%1 - cy\t%0,%1" - [(set_attr "op_type" "RR,RI,RX,RXY")]) + c<g>r\t%0,%1 + c<g>hi\t%0,%h1 + c<g>fi\t%0,%1 + c<g>\t%0,%1 + c<y>\t%0,%1" + [(set_attr "op_type" "RR<E>,RI,RIL,RX<Y>,RXY")]) ; Compare (unsigned) instructions (define_insn "*cmpdi_ccu_zero" - [(set (reg 33) + [(set (reg CC_REGNUM) (compare (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m")) (match_operand:DI 0 "register_operand" "d,d")))] - "s390_match_ccmode(insn, CCURmode) && TARGET_64BIT" + "s390_match_ccmode (insn, CCURmode) && TARGET_64BIT" "@ clgfr\t%0,%1 clgf\t%0,%1" [(set_attr "op_type" "RRE,RXY")]) (define_insn "*cmpdi_ccu" - [(set (reg 33) - (compare (match_operand:DI 0 "register_operand" "d,d") - (match_operand:DI 1 "general_operand" "d,m")))] - "s390_match_ccmode(insn, CCUmode) && TARGET_64BIT" + [(set (reg CC_REGNUM) + (compare (match_operand:DI 0 "nonimmediate_operand" "d,d,d,Q,BQ") + (match_operand:DI 1 "general_operand" "d,Op,m,BQ,Q")))] + "s390_match_ccmode (insn, CCUmode) && TARGET_64BIT" "@ clgr\t%0,%1 - clg\t%0,%1" - [(set_attr "op_type" "RRE,RXY")]) + clgfi\t%0,%1 + clg\t%0,%1 + # + #" + [(set_attr "op_type" "RRE,RIL,RXY,SS,SS")]) (define_insn "*cmpsi_ccu" - [(set (reg 33) - (compare (match_operand:SI 0 "register_operand" "d,d,d") - (match_operand:SI 1 "general_operand" "d,R,T")))] - "s390_match_ccmode(insn, CCUmode)" + [(set (reg CC_REGNUM) + (compare (match_operand:SI 0 "nonimmediate_operand" "d,d,d,d,Q,BQ") + (match_operand:SI 1 "general_operand" "d,Os,R,T,BQ,Q")))] + "s390_match_ccmode (insn, CCUmode)" "@ clr\t%0,%1 + clfi\t%0,%o1 cl\t%0,%1 - cly\t%0,%1" - [(set_attr "op_type" "RR,RX,RXY")]) + cly\t%0,%1 + # + #" + [(set_attr "op_type" "RR,RIL,RX,RXY,SS,SS")]) (define_insn "*cmphi_ccu" - [(set (reg 33) - (compare (match_operand:HI 0 "register_operand" "d,d") - (match_operand:HI 1 "s_imm_operand" "Q,S")))] - "s390_match_ccmode(insn, CCUmode)" - "@ - clm\t%0,3,%1 - clmy\t%0,3,%1" - [(set_attr "op_type" "RS,RSY")]) + [(set (reg CC_REGNUM) + (compare (match_operand:HI 0 "nonimmediate_operand" "d,d,Q,BQ") + (match_operand:HI 1 "general_operand" "Q,S,BQ,Q")))] + "s390_match_ccmode (insn, CCUmode) + && !register_operand (operands[1], HImode)" + "@ + clm\t%0,3,%S1 + clmy\t%0,3,%S1 + # + #" + [(set_attr "op_type" "RS,RSY,SS,SS")]) (define_insn "*cmpqi_ccu" - [(set (reg 33) - (compare (match_operand:QI 0 "register_operand" "d,d") - (match_operand:QI 1 "s_imm_operand" "Q,S")))] - "s390_match_ccmode(insn, CCUmode)" - "@ - clm\t%0,1,%1 - clmy\t%0,1,%1" - [(set_attr "op_type" "RS,RSY")]) + [(set (reg CC_REGNUM) + (compare (match_operand:QI 0 "nonimmediate_operand" "d,d,Q,S,Q,BQ") + (match_operand:QI 1 "general_operand" "Q,S,n,n,BQ,Q")))] + "s390_match_ccmode (insn, CCUmode) + && !register_operand (operands[1], QImode)" + "@ + clm\t%0,1,%S1 + clmy\t%0,1,%S1 + cli\t%S0,%b1 + cliy\t%S0,%b1 + # + #" + [(set_attr "op_type" "RS,RSY,SI,SIY,SS,SS")]) -(define_insn "*cli" - [(set (reg 33) - (compare (match_operand:QI 0 "memory_operand" "Q,S") - (match_operand:QI 1 "immediate_operand" "n,n")))] - "s390_match_ccmode (insn, CCUmode)" - "@ - cli\t%0,%b1 - cliy\t%0,%b1" - [(set_attr "op_type" "SI,SIY")]) -(define_insn "*cmpdi_ccu_mem" - [(set (reg 33) - (compare (match_operand:DI 0 "s_operand" "Q") - (match_operand:DI 1 "s_imm_operand" "Q")))] - "s390_match_ccmode(insn, CCUmode)" - "clc\t%O0(8,%R0),%1" - [(set_attr "op_type" "SS")]) +; Block compare (CLC) instruction patterns. -(define_insn "*cmpsi_ccu_mem" - [(set (reg 33) - (compare (match_operand:SI 0 "s_operand" "Q") - (match_operand:SI 1 "s_imm_operand" "Q")))] - "s390_match_ccmode(insn, CCUmode)" - "clc\t%O0(4,%R0),%1" - [(set_attr "op_type" "SS")]) - -(define_insn "*cmphi_ccu_mem" - [(set (reg 33) - (compare (match_operand:HI 0 "s_operand" "Q") - (match_operand:HI 1 "s_imm_operand" "Q")))] - "s390_match_ccmode(insn, CCUmode)" - "clc\t%O0(2,%R0),%1" +(define_insn "*clc" + [(set (reg CC_REGNUM) + (compare (match_operand:BLK 0 "memory_operand" "Q") + (match_operand:BLK 1 "memory_operand" "Q"))) + (use (match_operand 2 "const_int_operand" "n"))] + "s390_match_ccmode (insn, CCUmode) + && INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256" + "clc\t%O0(%2,%R0),%S1" [(set_attr "op_type" "SS")]) -(define_insn "*cmpqi_ccu_mem" - [(set (reg 33) - (compare (match_operand:QI 0 "s_operand" "Q") - (match_operand:QI 1 "s_imm_operand" "Q")))] - "s390_match_ccmode(insn, CCUmode)" - "clc\t%O0(1,%R0),%1" - [(set_attr "op_type" "SS")]) - - -; DF instructions - -(define_insn "*cmpdf_ccs_0" - [(set (reg 33) - (compare (match_operand:DF 0 "register_operand" "f") - (match_operand:DF 1 "const0_operand" "")))] - "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "ltdbr\t%0,%0" - [(set_attr "op_type" "RRE") - (set_attr "type" "fsimpd")]) - -(define_insn "*cmpdf_ccs_0_ibm" - [(set (reg 33) - (compare (match_operand:DF 0 "register_operand" "f") - (match_operand:DF 1 "const0_operand" "")))] - "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" - "ltdr\t%0,%0" - [(set_attr "op_type" "RR") - (set_attr "type" "fsimpd")]) - -(define_insn "*cmpdf_ccs" - [(set (reg 33) - (compare (match_operand:DF 0 "register_operand" "f,f") - (match_operand:DF 1 "general_operand" "f,R")))] - "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "@ - cdbr\t%0,%1 - cdb\t%0,%1" - [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fsimpd")]) +(define_split + [(set (reg CC_REGNUM) + (compare (match_operand 0 "memory_operand" "") + (match_operand 1 "memory_operand" "")))] + "reload_completed + && s390_match_ccmode (insn, CCUmode) + && GET_MODE (operands[0]) == GET_MODE (operands[1]) + && GET_MODE_SIZE (GET_MODE (operands[0])) > 0" + [(parallel + [(set (match_dup 0) (match_dup 1)) + (use (match_dup 2))])] +{ + operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0]))); + operands[0] = adjust_address (operands[0], BLKmode, 0); + operands[1] = adjust_address (operands[1], BLKmode, 0); -(define_insn "*cmpdf_ccs_ibm" - [(set (reg 33) - (compare (match_operand:DF 0 "register_operand" "f,f") - (match_operand:DF 1 "general_operand" "f,R")))] - "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" - "@ - cdr\t%0,%1 - cd\t%0,%1" - [(set_attr "op_type" "RR,RX") - (set_attr "type" "fsimpd")]) + operands[1] = gen_rtx_COMPARE (GET_MODE (SET_DEST (PATTERN (curr_insn))), + operands[0], operands[1]); + operands[0] = SET_DEST (PATTERN (curr_insn)); +}) -; SF instructions +; (DF|SF) instructions -(define_insn "*cmpsf_ccs_0" - [(set (reg 33) - (compare (match_operand:SF 0 "register_operand" "f") - (match_operand:SF 1 "const0_operand" "")))] +; ltxbr, ltdbr, ltebr +(define_insn "*cmp<mode>_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" - "ltebr\t%0,%0" + "lt<xde>br\t%0,%0" [(set_attr "op_type" "RRE") - (set_attr "type" "fsimps")]) + (set_attr "type" "fsimp<mode>")]) -(define_insn "*cmpsf_ccs_0_ibm" - [(set (reg 33) - (compare (match_operand:SF 0 "register_operand" "f") - (match_operand:SF 1 "const0_operand" "")))] +; ltxr, ltdr, lter +(define_insn "*cmp<mode>_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" - "lter\t%0,%0" - [(set_attr "op_type" "RR") - (set_attr "type" "fsimps")]) - -(define_insn "*cmpsf_ccs" - [(set (reg 33) - (compare (match_operand:SF 0 "register_operand" "f,f") - (match_operand:SF 1 "general_operand" "f,R")))] + "lt<xde>r\t%0,%0" + [(set_attr "op_type" "<RRe>") + (set_attr "type" "fsimp<mode>")]) + +; cxbr, cdbr, cebr, cxb, cdb, ceb +(define_insn "*cmp<mode>_ccs" + [(set (reg CC_REGNUM) + (compare (match_operand:FPR 0 "register_operand" "f,f") + (match_operand:FPR 1 "general_operand" "f,<Rf>")))] "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" "@ - cebr\t%0,%1 - ceb\t%0,%1" + c<xde>br\t%0,%1 + c<xde>b\t%0,%1" [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fsimps")]) + (set_attr "type" "fsimp<mode>")]) -(define_insn "*cmpsf_ccs" - [(set (reg 33) - (compare (match_operand:SF 0 "register_operand" "f,f") - (match_operand:SF 1 "general_operand" "f,R")))] +; cxr, cdr, cer, cx, cd, ce +(define_insn "*cmp<mode>_ccs_ibm" + [(set (reg CC_REGNUM) + (compare (match_operand:FPR 0 "register_operand" "f,f") + (match_operand:FPR 1 "general_operand" "f,<Rf>")))] "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" "@ - cer\t%0,%1 - ce\t%0,%1" - [(set_attr "op_type" "RR,RX") - (set_attr "type" "fsimps")]) + c<xde>r\t%0,%1 + c<xde>\t%0,%1" + [(set_attr "op_type" "<RRe>,<RXe>") + (set_attr "type" "fsimp<mode>")]) ;; @@ -987,16 +794,16 @@ (define_insn "movti" [(set (match_operand:TI 0 "nonimmediate_operand" "=d,QS,d,o,Q") - (match_operand:TI 1 "general_operand" "QS,d,dKm,d,Q"))] + (match_operand:TI 1 "general_operand" "QS,d,dPm,d,Q"))] "TARGET_64BIT" "@ - lmg\t%0,%N0,%1 - stmg\t%1,%N1,%0 + lmg\t%0,%N0,%S1 + stmg\t%1,%N1,%S0 # # - mvc\t%O0(16,%R0),%1" - [(set_attr "op_type" "RSY,RSY,NN,NN,SS") - (set_attr "type" "lm,stm,*,*,cs")]) + #" + [(set_attr "op_type" "RSY,RSY,*,*,SS") + (set_attr "type" "lm,stm,*,*,*")]) (define_split [(set (match_operand:TI 0 "nonimmediate_operand" "") @@ -1044,9 +851,8 @@ (match_operand:DI 2 "register_operand" "=&a")])] "TARGET_64BIT" { - if (GET_CODE (operands[0]) != MEM) - abort (); - s390_load_address (operands[2], XEXP (operands[0], 0)); + 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; @@ -1062,16 +868,12 @@ "" { /* 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); - - /* During and after reload, we need to force constants - to the literal pool ourselves, if necessary. */ - if ((reload_in_progress || reload_completed) - && CONSTANT_P (operands[1]) - && (!legitimate_reload_constant_p (operands[1]) - || FP_REG_P (operands[0]))) - operands[1] = force_const_mem (DImode, operands[1]); }) (define_insn "*movdi_larl" @@ -1083,12 +885,46 @@ [(set_attr "op_type" "RIL") (set_attr "type" "larl")]) +(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") + (match_operand:DI 1 "general_operand" + "K,N0HD0,N1HD0,N2HD0,N3HD0,Os,N0SD0,N1SD0,L,d,m,d,*f,R,T,*f,*f,t,d,t,Q,?Q"))] + "TARGET_64BIT && TARGET_EXTIMM" + "@ + 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 + 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,RXY,RRE,RXY,RXY, + RR,RX,RXY,RX,RXY,*,*,RS,RS,SS") + (set_attr "type" "*,*,*,*,*,*,*,*,la,lr,load,store, + floaddf,floaddf,floaddf,fstoredf,fstoredf,*,*,*,*,*")]) + (define_insn "*movdi_64" - [(set (match_operand:DI 0 "nonimmediate_operand" - "=d,d,d,d,d,d,d,d,m,!*f,!*f,!*f,!R,!T,?Q") - (match_operand:DI 1 "general_operand" - "K,N0HD0,N1HD0,N2HD0,N3HD0,L,d,m,d,*f,R,T,*f,*f,?Q"))] - "TARGET_64BIT" + [(set (match_operand:DI 0 "nonimmediate_operand" + "=d,d,d,d,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,L,d,m,d,*f,R,T,*f,*f,t,d,t,Q,?Q"))] + "TARGET_64BIT && !TARGET_EXTIMM" "@ lghi\t%0,%h1 llihh\t%0,%i1 @@ -1104,18 +940,58 @@ ldy\t%0,%1 std\t%1,%0 stdy\t%1,%0 - mvc\t%O0(8,%R0),%1" - [(set_attr "op_type" "RI,RI,RI,RI,RI,RXY,RRE,RXY,RXY,RR,RX,RXY,RX,RXY,SS") - (set_attr "type" "*,*,*,*,*,la,lr,load,store,floadd,floadd,floadd, - fstored,fstored,cs")]) + # + # + stam\t%1,%N1,%S0 + lam\t%0,%N0,%S1 + #" + [(set_attr "op_type" "RI,RI,RI,RI,RI,RXY,RRE,RXY,RXY, + RR,RX,RXY,RX,RXY,*,*,RS,RS,SS") + (set_attr "type" "*,*,*,*,*,la,lr,load,store, + floaddf,floaddf,floaddf,fstoredf,fstoredf,*,*,*,*,*")]) + +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "register_operand" ""))] + "TARGET_64BIT && ACCESS_REG_P (operands[1])" + [(set (match_dup 2) (match_dup 3)) + (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 32))) + (set (strict_low_part (match_dup 2)) (match_dup 4))] + "operands[2] = gen_lowpart (SImode, operands[0]); + s390_split_access_reg (operands[1], &operands[4], &operands[3]);") + +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "register_operand" ""))] + "TARGET_64BIT && ACCESS_REG_P (operands[0]) + && dead_or_set_p (insn, operands[1])" + [(set (match_dup 3) (match_dup 2)) + (set (match_dup 1) (lshiftrt:DI (match_dup 1) (const_int 32))) + (set (match_dup 4) (match_dup 2))] + "operands[2] = gen_lowpart (SImode, operands[1]); + s390_split_access_reg (operands[0], &operands[3], &operands[4]);") + +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "register_operand" ""))] + "TARGET_64BIT && ACCESS_REG_P (operands[0]) + && !dead_or_set_p (insn, operands[1])" + [(set (match_dup 3) (match_dup 2)) + (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32))) + (set (match_dup 4) (match_dup 2)) + (set (match_dup 1) (rotate:DI (match_dup 1) (const_int 32)))] + "operands[2] = gen_lowpart (SImode, operands[1]); + s390_split_access_reg (operands[0], &operands[3], &operands[4]);") (define_insn "*movdi_31" - [(set (match_operand:DI 0 "nonimmediate_operand" "=d,Q,d,o,!*f,!*f,!*f,!R,!T,Q") - (match_operand:DI 1 "general_operand" "Q,d,dKm,d,*f,R,T,*f,*f,Q"))] + [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,Q,S,d,o,!*f,!*f,!*f,!R,!T,Q") + (match_operand:DI 1 "general_operand" "Q,S,d,d,dPm,d,*f,R,T,*f,*f,Q"))] "!TARGET_64BIT" "@ - lm\t%0,%N0,%1 - stm\t%1,%N1,%0 + lm\t%0,%N0,%S1 + lmy\t%0,%N0,%S1 + stm\t%1,%N1,%S0 + stmy\t%1,%N1,%S0 # # ldr\t%0,%1 @@ -1123,9 +999,9 @@ ldy\t%0,%1 std\t%1,%0 stdy\t%1,%0 - mvc\t%O0(8,%R0),%1" - [(set_attr "op_type" "RS,RS,NN,NN,RR,RX,RXY,RX,RXY,SS") - (set_attr "type" "lm,stm,*,*,floadd,floadd,floadd,fstored,fstored,cs")]) + #" + [(set_attr "op_type" "RS,RSY,RS,RSY,*,*,RR,RX,RXY,RX,RXY,SS") + (set_attr "type" "lm,lm,stm,stm,*,*,floaddf,floaddf,floaddf,fstoredf,fstoredf,*")]) (define_split [(set (match_operand:DI 0 "nonimmediate_operand" "") @@ -1174,9 +1050,8 @@ (match_operand:SI 2 "register_operand" "=&a")])] "!TARGET_64BIT" { - if (GET_CODE (operands[0]) != MEM) - abort (); - s390_load_address (operands[2], XEXP (operands[0], 0)); + 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; @@ -1208,10 +1083,9 @@ [(parallel [(set (match_operand:DI 0 "register_operand" "") (match_operand:QI 1 "address_operand" "")) - (clobber (reg:CC 33))])] + (clobber (reg:CC CC_REGNUM))])] "TARGET_64BIT - && strict_memory_address_p (VOIDmode, operands[1]) - && preferred_la_operand_p (operands[1])" + && preferred_la_operand_p (operands[1], const0_rtx)" [(set (match_dup 0) (match_dup 1))] "") @@ -1222,11 +1096,10 @@ [(set (match_dup 0) (plus:DI (match_dup 0) (match_operand:DI 2 "nonmemory_operand" ""))) - (clobber (reg:CC 33))])] + (clobber (reg:CC CC_REGNUM))])] "TARGET_64BIT && !reg_overlap_mentioned_p (operands[0], operands[2]) - && strict_memory_address_p (VOIDmode, gen_rtx_PLUS (DImode, operands[1], operands[2])) - && preferred_la_operand_p (gen_rtx_PLUS (DImode, operands[1], operands[2]))" + && preferred_la_operand_p (operands[1], operands[2])" [(set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))] "") @@ -1250,29 +1123,12 @@ "" { /* 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); - - /* expr.c tries to load an effective address using - force_reg. This fails because we don't have a - generic load_address pattern. Convert the move - to a proper arithmetic operation instead, unless - it is guaranteed to be OK. */ - if (GET_CODE (operands[1]) == PLUS - && !legitimate_la_operand_p (operands[1])) - { - operands[1] = force_operand (operands[1], operands[0]); - if (operands[1] == operands[0]) - DONE; - } - - /* During and after reload, we need to force constants - to the literal pool ourselves, if necessary. */ - if ((reload_in_progress || reload_completed) - && CONSTANT_P (operands[1]) - && (!legitimate_reload_constant_p (operands[1]) - || FP_REG_P (operands[0]))) - operands[1] = force_const_mem (SImode, operands[1]); }) (define_insn "*movsi_larl" @@ -1285,15 +1141,16 @@ (set_attr "type" "larl")]) (define_insn "*movsi_zarch" - [(set (match_operand:SI 0 "nonimmediate_operand" - "=d,d,d,d,d,d,d,R,T,!*f,!*f,!*f,!R,!T,?Q") - (match_operand:SI 1 "general_operand" - "K,N0HS0,N1HS0,L,d,R,T,d,d,*f,R,T,*f,*f,?Q"))] + [(set (match_operand:SI 0 "nonimmediate_operand" + "=d,d,d,d,d,d,d,d,R,T,!*f,!*f,!*f,!R,!T,d,t,Q,t,?Q") + (match_operand:SI 1 "general_operand" + "K,N0HS0,N1HS0,Os,L,d,R,T,d,d,*f,R,T,*f,*f,t,d,t,Q,?Q"))] "TARGET_ZARCH" "@ lhi\t%0,%h1 llilh\t%0,%i1 llill\t%0,%i1 + iilf\t%0,%o1 lay\t%0,%a1 lr\t%0,%1 l\t%0,%1 @@ -1305,13 +1162,19 @@ ley\t%0,%1 ste\t%1,%0 stey\t%1,%0 - mvc\t%O0(4,%R0),%1" - [(set_attr "op_type" "RI,RI,RI,RXY,RR,RX,RXY,RX,RXY,RR,RX,RXY,RX,RXY,SS") - (set_attr "type" "*,*,*,la,lr,load,load,store,store,floads,floads,floads,fstores,fstores,cs")]) + ear\t%0,%1 + sar\t%0,%1 + stam\t%1,%1,%S0 + lam\t%0,%0,%S1 + #" + [(set_attr "op_type" "RI,RI,RI,RIL,RXY,RR,RX,RXY,RX,RXY, + RR,RX,RXY,RX,RXY,RRE,RRE,RS,RS,SS") + (set_attr "type" "*,*,*,*,la,lr,load,load,store,store, + floadsf,floadsf,floadsf,fstoresf,fstoresf,*,*,*,*,*")]) (define_insn "*movsi_esa" - [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,!*f,!*f,!R,?Q") - (match_operand:SI 1 "general_operand" "K,d,R,d,*f,R,*f,?Q"))] + [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,!*f,!*f,!R,d,t,Q,t,?Q") + (match_operand:SI 1 "general_operand" "K,d,R,d,*f,R,*f,t,d,t,Q,?Q"))] "!TARGET_ZARCH" "@ lhi\t%0,%h1 @@ -1321,9 +1184,13 @@ ler\t%0,%1 le\t%0,%1 ste\t%1,%0 - mvc\t%O0(4,%R0),%1" - [(set_attr "op_type" "RI,RR,RX,RX,RR,RX,RX,SS") - (set_attr "type" "*,lr,load,store,floads,floads,fstores,cs")]) + ear\t%0,%1 + sar\t%0,%1 + stam\t%1,%1,%S0 + lam\t%0,%0,%S1 + #" + [(set_attr "op_type" "RI,RR,RX,RX,RR,RX,RX,RRE,RRE,RS,RS,SS") + (set_attr "type" "*,lr,load,store,floadsf,floadsf,fstoresf,*,*,*,*,*")]) (define_peephole2 [(set (match_operand:SI 0 "register_operand" "") @@ -1350,10 +1217,9 @@ [(parallel [(set (match_operand:SI 0 "register_operand" "") (match_operand:QI 1 "address_operand" "")) - (clobber (reg:CC 33))])] + (clobber (reg:CC CC_REGNUM))])] "!TARGET_64BIT - && strict_memory_address_p (VOIDmode, operands[1]) - && preferred_la_operand_p (operands[1])" + && preferred_la_operand_p (operands[1], const0_rtx)" [(set (match_dup 0) (match_dup 1))] "") @@ -1364,11 +1230,10 @@ [(set (match_dup 0) (plus:SI (match_dup 0) (match_operand:SI 2 "nonmemory_operand" ""))) - (clobber (reg:CC 33))])] + (clobber (reg:CC CC_REGNUM))])] "!TARGET_64BIT && !reg_overlap_mentioned_p (operands[0], operands[2]) - && strict_memory_address_p (VOIDmode, gen_rtx_PLUS (SImode, operands[1], operands[2])) - && preferred_la_operand_p (gen_rtx_PLUS (SImode, operands[1], operands[2]))" + && preferred_la_operand_p (operands[1], operands[2])" [(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))] "") @@ -1387,7 +1252,7 @@ [(set (match_operand:SI 0 "register_operand" "=d") (and:SI (match_operand:QI 1 "address_operand" "p") (const_int 2147483647))) - (clobber (reg:CC 33))] + (clobber (reg:CC CC_REGNUM))] "!TARGET_64BIT" "#" "&& reload_completed" @@ -1427,12 +1292,11 @@ (match_operand:HI 1 "general_operand" ""))] "" { - /* Make it explicit that loading a register from memory + /* Make it explicit that loading a register from memory always sign-extends (at least) to SImode. */ if (optimize && !no_new_pseudos && register_operand (operands[0], VOIDmode) - && GET_CODE (operands[1]) == MEM - && GET_CODE (XEXP (operands[1], 0)) != ADDRESSOF) + && GET_CODE (operands[1]) == MEM) { rtx tmp = gen_reg_rtx (SImode); rtx ext = gen_rtx_SIGN_EXTEND (SImode, operands[1]); @@ -1452,9 +1316,9 @@ lhy\t%0,%1 sth\t%1,%0 sthy\t%1,%0 - mvc\t%O0(2,%R0),%1" + #" [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SS") - (set_attr "type" "lr,*,*,*,store,store,cs")]) + (set_attr "type" "lr,*,*,*,store,store,*")]) (define_peephole2 [(set (match_operand:HI 0 "register_operand" "") @@ -1479,8 +1343,7 @@ is just as fast as a QImode load. */ if (TARGET_ZARCH && optimize && !no_new_pseudos && register_operand (operands[0], VOIDmode) - && GET_CODE (operands[1]) == MEM - && GET_CODE (XEXP (operands[1], 0)) != ADDRESSOF) + && GET_CODE (operands[1]) == MEM) { rtx tmp = gen_reg_rtx (word_mode); rtx ext = gen_rtx_ZERO_EXTEND (word_mode, operands[1]); @@ -1500,11 +1363,11 @@ icy\t%0,%1 stc\t%1,%0 stcy\t%1,%0 - mvi\t%0,%b1 - mviy\t%0,%b1 - mvc\t%O0(1,%R0),%1" + mvi\t%S0,%b1 + mviy\t%S0,%b1 + #" [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SI,SIY,SS") - (set_attr "type" "lr,*,*,*,store,store,store,store,cs")]) + (set_attr "type" "lr,*,*,*,store,store,store,store,*")]) (define_peephole2 [(set (match_operand:QI 0 "nonimmediate_operand" "") @@ -1535,12 +1398,12 @@ (define_insn "*movstricthi" [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d,d")) - (match_operand:HI 1 "s_imm_operand" "Q,S")) - (clobber (reg:CC 33))] + (match_operand:HI 1 "memory_operand" "Q,S")) + (clobber (reg:CC CC_REGNUM))] "" "@ - icm\t%0,3,%1 - icmy\t%0,3,%1" + icm\t%0,3,%S1 + icmy\t%0,3,%S1" [(set_attr "op_type" "RS,RSY")]) ; @@ -1548,15 +1411,159 @@ ; (define_insn "movstrictsi" - [(set (strict_low_part (match_operand:SI 0 "register_operand" "+d,d,d")) - (match_operand:SI 1 "general_operand" "d,R,T"))] + [(set (strict_low_part (match_operand:SI 0 "register_operand" "+d,d,d,d")) + (match_operand:SI 1 "general_operand" "d,R,T,t"))] "TARGET_64BIT" "@ lr\t%0,%1 l\t%0,%1 - ly\t%0,%1" - [(set_attr "op_type" "RR,RX,RXY") - (set_attr "type" "lr,load,load")]) + ly\t%0,%1 + ear\t%0,%1" + [(set_attr "op_type" "RR,RX,RXY,RRE") + (set_attr "type" "lr,load,load,*")]) + +; +; movtf instruction pattern(s). +; + +(define_expand "movtf" + [(set (match_operand:TF 0 "nonimmediate_operand" "") + (match_operand:TF 1 "general_operand" ""))] + "" + "") + +(define_insn "*movtf_64" + [(set (match_operand:TF 0 "nonimmediate_operand" "=f,f,f,o,d,QS,d,o,Q") + (match_operand:TF 1 "general_operand" "G,f,o,f,QS,d,dm,d,Q"))] + "TARGET_64BIT" + "@ + lzxr\t%0 + 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 "*movtf_31" + [(set (match_operand:TF 0 "nonimmediate_operand" "=f,f,f,o,Q") + (match_operand:TF 1 "general_operand" "G,f,o,f,Q"))] + "!TARGET_64BIT" + "@ + lzxr\t%0 + lxr\t%0,%1 + # + # + #" + [(set_attr "op_type" "RRE,RRE,*,*,*") + (set_attr "type" "fsimptf,fsimptf,*,*,*")]) + +; TFmode in GPRs splitters + +(define_split + [(set (match_operand:TF 0 "nonimmediate_operand" "") + (match_operand:TF 1 "general_operand" ""))] + "TARGET_64BIT && reload_completed + && s390_split_ok_p (operands[0], operands[1], TFmode, 0)" + [(set (match_dup 2) (match_dup 4)) + (set (match_dup 3) (match_dup 5))] +{ + operands[2] = operand_subword (operands[0], 0, 0, TFmode); + operands[3] = operand_subword (operands[0], 1, 0, TFmode); + operands[4] = operand_subword (operands[1], 0, 0, TFmode); + operands[5] = operand_subword (operands[1], 1, 0, TFmode); +}) + +(define_split + [(set (match_operand:TF 0 "nonimmediate_operand" "") + (match_operand:TF 1 "general_operand" ""))] + "TARGET_64BIT && reload_completed + && s390_split_ok_p (operands[0], operands[1], TFmode, 1)" + [(set (match_dup 2) (match_dup 4)) + (set (match_dup 3) (match_dup 5))] +{ + operands[2] = operand_subword (operands[0], 1, 0, TFmode); + operands[3] = operand_subword (operands[0], 0, 0, TFmode); + operands[4] = operand_subword (operands[1], 1, 0, TFmode); + operands[5] = operand_subword (operands[1], 0, 0, TFmode); +}) + +(define_split + [(set (match_operand:TF 0 "register_operand" "") + (match_operand:TF 1 "memory_operand" ""))] + "TARGET_64BIT && reload_completed + && !FP_REG_P (operands[0]) + && !s_operand (operands[1], VOIDmode)" + [(set (match_dup 0) (match_dup 1))] +{ + rtx addr = operand_subword (operands[0], 1, 0, DFmode); + s390_load_address (addr, XEXP (operands[1], 0)); + operands[1] = replace_equiv_address (operands[1], addr); +}) + +; TFmode in FPRs splitters + +(define_split + [(set (match_operand:TF 0 "register_operand" "") + (match_operand:TF 1 "memory_operand" ""))] + "reload_completed && offsettable_memref_p (operands[1]) + && FP_REG_P (operands[0])" + [(set (match_dup 2) (match_dup 4)) + (set (match_dup 3) (match_dup 5))] +{ + operands[2] = simplify_gen_subreg (DFmode, operands[0], TFmode, 0); + operands[3] = simplify_gen_subreg (DFmode, operands[0], TFmode, 8); + operands[4] = adjust_address_nv (operands[1], DFmode, 0); + operands[5] = adjust_address_nv (operands[1], DFmode, 8); +}) + +(define_split + [(set (match_operand:TF 0 "memory_operand" "") + (match_operand:TF 1 "register_operand" ""))] + "reload_completed && offsettable_memref_p (operands[0]) + && FP_REG_P (operands[1])" + [(set (match_dup 2) (match_dup 4)) + (set (match_dup 3) (match_dup 5))] +{ + operands[2] = adjust_address_nv (operands[0], DFmode, 0); + operands[3] = adjust_address_nv (operands[0], DFmode, 8); + operands[4] = simplify_gen_subreg (DFmode, operands[1], TFmode, 0); + operands[5] = simplify_gen_subreg (DFmode, operands[1], TFmode, 8); +}) + +(define_expand "reload_outtf" + [(parallel [(match_operand:TF 0 "" "") + (match_operand:TF 1 "register_operand" "f") + (match_operand:SI 2 "register_operand" "=&a")])] + "" +{ + rtx addr = gen_lowpart (Pmode, operands[2]); + + gcc_assert (MEM_P (operands[0])); + s390_load_address (addr, find_replacement (&XEXP (operands[0], 0))); + operands[0] = replace_equiv_address (operands[0], addr); + emit_move_insn (operands[0], operands[1]); + DONE; +}) + +(define_expand "reload_intf" + [(parallel [(match_operand:TF 0 "register_operand" "=f") + (match_operand:TF 1 "" "") + (match_operand:SI 2 "register_operand" "=&a")])] + "" +{ + rtx addr = gen_lowpart (Pmode, operands[2]); + + gcc_assert (MEM_P (operands[1])); + s390_load_address (addr, find_replacement (&XEXP (operands[1], 0))); + operands[1] = replace_equiv_address (operands[1], addr); + emit_move_insn (operands[0], operands[1]); + DONE; +}) ; ; movdf instruction pattern(s). @@ -1566,19 +1573,14 @@ [(set (match_operand:DF 0 "nonimmediate_operand" "") (match_operand:DF 1 "general_operand" ""))] "" -{ - /* During and after reload, we need to force constants - to the literal pool ourselves, if necessary. */ - if ((reload_in_progress || reload_completed) - && CONSTANT_P (operands[1])) - operands[1] = force_const_mem (DFmode, operands[1]); -}) + "") (define_insn "*movdf_64" - [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,R,T,d,d,m,?Q") - (match_operand:DF 1 "general_operand" "f,R,T,f,f,d,m,d,?Q"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,m,?Q") + (match_operand:DF 1 "general_operand" "G,f,R,T,f,f,d,m,d,?Q"))] "TARGET_64BIT" "@ + lzdr\t%0 ldr\t%0,%1 ld\t%0,%1 ldy\t%0,%1 @@ -1587,27 +1589,31 @@ lgr\t%0,%1 lg\t%0,%1 stg\t%1,%0 - mvc\t%O0(8,%R0),%1" - [(set_attr "op_type" "RR,RX,RXY,RX,RXY,RRE,RXY,RXY,SS") - (set_attr "type" "floadd,floadd,floadd,fstored,fstored,lr,load,store,cs")]) + #" + [(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,R,T,d,Q,d,o,Q") - (match_operand:DF 1 "general_operand" "f,R,T,f,f,Q,d,dKm,d,Q"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,Q,S,d,o,Q") + (match_operand:DF 1 "general_operand" "G,f,R,T,f,f,Q,S,d,d,dPm,d,Q"))] "!TARGET_64BIT" "@ + lzdr\t%0 ldr\t%0,%1 ld\t%0,%1 ldy\t%0,%1 std\t%1,%0 stdy\t%1,%0 - lm\t%0,%N0,%1 - stm\t%1,%N1,%0 + lm\t%0,%N0,%S1 + lmy\t%0,%N0,%S1 + stm\t%1,%N1,%S0 + stmy\t%1,%N1,%S0 # # - mvc\t%O0(8,%R0),%1" - [(set_attr "op_type" "RR,RX,RXY,RX,RXY,RS,RS,NN,NN,SS") - (set_attr "type" "floadd,floadd,floadd,fstored,fstored,lm,stm,*,*,cs")]) + #" + [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RS,RSY,RS,RSY,*,*,SS") + (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,fstoredf,fstoredf,\ + lm,lm,stm,stm,*,*,*")]) (define_split [(set (match_operand:DF 0 "nonimmediate_operand" "") @@ -1656,9 +1662,8 @@ (match_operand:SI 2 "register_operand" "=&a")])] "!TARGET_64BIT" { - if (GET_CODE (operands[0]) != MEM) - abort (); - s390_load_address (operands[2], XEXP (operands[0], 0)); + 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; @@ -1668,23 +1673,12 @@ ; movsf instruction pattern(s). ; -(define_expand "movsf" - [(set (match_operand:SF 0 "nonimmediate_operand" "") - (match_operand:SF 1 "general_operand" ""))] - "" -{ - /* During and after reload, we need to force constants - to the literal pool ourselves, if necessary. */ - if ((reload_in_progress || reload_completed) - && CONSTANT_P (operands[1])) - operands[1] = force_const_mem (SFmode, operands[1]); -}) - -(define_insn "*movsf" - [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,R,T,d,d,d,R,T,?Q") - (match_operand:SF 1 "general_operand" "f,R,T,f,f,d,R,T,d,d,?Q"))] +(define_insn "movsf" + [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,d,R,T,?Q") + (match_operand:SF 1 "general_operand" "G,f,R,T,f,f,d,R,T,d,d,?Q"))] "" "@ + lzer\t%0 ler\t%0,%1 le\t%0,%1 ley\t%0,%1 @@ -1695,9 +1689,78 @@ ly\t%0,%1 st\t%1,%0 sty\t%1,%0 - mvc\t%O0(4,%R0),%1" - [(set_attr "op_type" "RR,RX,RXY,RX,RXY,RR,RX,RXY,RX,RXY,SS") - (set_attr "type" "floads,floads,floads,fstores,fstores,lr,load,load,store,store,cs")]) + #" + [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RR,RX,RXY,RX,RXY,SS") + (set_attr "type" "fsimpsf,floadsf,floadsf,floadsf,fstoresf,fstoresf, + lr,load,load,store,store,*")]) + +; +; movcc instruction pattern +; + +(define_insn "movcc" + [(set (match_operand:CC 0 "nonimmediate_operand" "=d,c,d,d,d,R,T") + (match_operand:CC 1 "nonimmediate_operand" "d,d,c,R,T,d,d"))] + "" + "@ + lr\t%0,%1 + tmh\t%1,12288 + ipm\t%0 + st\t%0,%1 + sty\t%0,%1 + l\t%1,%0 + ly\t%1,%0" + [(set_attr "op_type" "RR,RI,RRE,RX,RXY,RX,RXY") + (set_attr "type" "lr,*,*,store,store,load,load")]) + +; +; Block move (MVC) patterns. +; + +(define_insn "*mvc" + [(set (match_operand:BLK 0 "memory_operand" "=Q") + (match_operand:BLK 1 "memory_operand" "Q")) + (use (match_operand 2 "const_int_operand" "n"))] + "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256" + "mvc\t%O0(%2,%R0),%S1" + [(set_attr "op_type" "SS")]) + +(define_split + [(set (match_operand 0 "memory_operand" "") + (match_operand 1 "memory_operand" ""))] + "reload_completed + && GET_MODE (operands[0]) == GET_MODE (operands[1]) + && GET_MODE_SIZE (GET_MODE (operands[0])) > 0" + [(parallel + [(set (match_dup 0) (match_dup 1)) + (use (match_dup 2))])] +{ + operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0]))); + operands[0] = adjust_address (operands[0], BLKmode, 0); + operands[1] = adjust_address (operands[1], BLKmode, 0); +}) + +(define_peephole2 + [(parallel + [(set (match_operand:BLK 0 "memory_operand" "") + (match_operand:BLK 1 "memory_operand" "")) + (use (match_operand 2 "const_int_operand" ""))]) + (parallel + [(set (match_operand:BLK 3 "memory_operand" "") + (match_operand:BLK 4 "memory_operand" "")) + (use (match_operand 5 "const_int_operand" ""))])] + "s390_offset_p (operands[0], operands[3], operands[2]) + && s390_offset_p (operands[1], operands[4], operands[2]) + && !s390_overlap_p (operands[0], operands[1], + INTVAL (operands[2]) + INTVAL (operands[5])) + && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256" + [(parallel + [(set (match_dup 6) (match_dup 7)) + (use (match_dup 8))])] + "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0)); + operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0)); + operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));") + ; ; load_multiple pattern(s). @@ -1751,9 +1814,6 @@ } else FAIL; - - if (from == frame_pointer_rtx || from == arg_pointer_rtx) - FAIL; } else { @@ -1776,7 +1836,7 @@ { int words = XVECLEN (operands[0], 0); operands[0] = gen_rtx_REG (DImode, REGNO (operands[1]) + words - 1); - return "lmg\t%1,%0,%2"; + return "lmg\t%1,%0,%S2"; } [(set_attr "op_type" "RSY") (set_attr "type" "lm")]) @@ -1789,7 +1849,7 @@ { int words = XVECLEN (operands[0], 0); operands[0] = gen_rtx_REG (SImode, REGNO (operands[1]) + words - 1); - return which_alternative == 0 ? "lm\t%1,%0,%2" : "lmy\t%1,%0,%2"; + return which_alternative == 0 ? "lm\t%1,%0,%S2" : "lmy\t%1,%0,%S2"; } [(set_attr "op_type" "RS,RSY") (set_attr "type" "lm")]) @@ -1844,9 +1904,6 @@ } else FAIL; - - if (to == frame_pointer_rtx || to == arg_pointer_rtx) - FAIL; } else { @@ -1870,7 +1927,7 @@ { int words = XVECLEN (operands[0], 0); operands[0] = gen_rtx_REG (DImode, REGNO (operands[2]) + words - 1); - return "stmg\t%2,%0,%1"; + return "stmg\t%2,%0,%S1"; } [(set_attr "op_type" "RSY") (set_attr "type" "stm")]) @@ -1884,7 +1941,7 @@ { int words = XVECLEN (operands[0], 0); operands[0] = gen_rtx_REG (SImode, REGNO (operands[2]) + words - 1); - return which_alternative == 0 ? "stm\t%2,%0,%1" : "stmy\t%2,%0,%1"; + return which_alternative == 0 ? "stm\t%2,%0,%S1" : "stmy\t%2,%0,%S1"; } [(set_attr "op_type" "RS,RSY") (set_attr "type" "stm")]) @@ -1893,144 +1950,225 @@ ;; String instructions. ;; +(define_insn "*execute" + [(match_parallel 0 "" + [(unspec [(match_operand 1 "register_operand" "a") + (match_operand:BLK 2 "memory_operand" "R") + (match_operand 3 "" "")] UNSPEC_EXECUTE)])] + "GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT + && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD" + "ex\t%1,%2" + [(set_attr "op_type" "RX") + (set_attr "type" "cs")]) + + ; ; strlenM instruction pattern(s). ; -(define_expand "strlendi" - [(set (reg:QI 0) (match_operand:QI 2 "immediate_operand" "")) - (parallel +(define_expand "strlen<mode>" + [(set (reg:SI 0) (match_operand:SI 2 "immediate_operand" "")) + (parallel [(set (match_dup 4) - (unspec:DI [(const_int 0) + (unspec:P [(const_int 0) (match_operand:BLK 1 "memory_operand" "") - (reg:QI 0) + (reg:SI 0) (match_operand 3 "immediate_operand" "")] UNSPEC_SRST)) - (clobber (scratch:DI)) - (clobber (reg:CC 33))]) + (clobber (scratch:P)) + (clobber (reg:CC CC_REGNUM))]) (parallel - [(set (match_operand:DI 0 "register_operand" "") - (minus:DI (match_dup 4) (match_dup 5))) - (clobber (reg:CC 33))])] - "TARGET_64BIT" + [(set (match_operand:P 0 "register_operand" "") + (minus:P (match_dup 4) (match_dup 5))) + (clobber (reg:CC CC_REGNUM))])] + "" { - operands[4] = gen_reg_rtx (DImode); - operands[5] = gen_reg_rtx (DImode); + operands[4] = gen_reg_rtx (Pmode); + operands[5] = gen_reg_rtx (Pmode); emit_move_insn (operands[5], force_operand (XEXP (operands[1], 0), NULL_RTX)); operands[1] = replace_equiv_address (operands[1], operands[5]); }) -(define_insn "*strlendi" - [(set (match_operand:DI 0 "register_operand" "=a") - (unspec:DI [(match_operand:DI 2 "general_operand" "0") - (mem:BLK (match_operand:DI 3 "register_operand" "1")) - (reg:QI 0) +(define_insn "*strlen<mode>" + [(set (match_operand:P 0 "register_operand" "=a") + (unspec:P [(match_operand:P 2 "general_operand" "0") + (mem:BLK (match_operand:P 3 "register_operand" "1")) + (reg:SI 0) (match_operand 4 "immediate_operand" "")] UNSPEC_SRST)) - (clobber (match_scratch:DI 1 "=a")) - (clobber (reg:CC 33))] - "TARGET_64BIT" + (clobber (match_scratch:P 1 "=a")) + (clobber (reg:CC CC_REGNUM))] + "" "srst\t%0,%1\;jo\t.-4" - [(set_attr "op_type" "NN") - (set_attr "type" "vs") - (set_attr "length" "8")]) + [(set_attr "length" "8") + (set_attr "type" "vs")]) -(define_expand "strlensi" - [(set (reg:QI 0) (match_operand:QI 2 "immediate_operand" "")) - (parallel - [(set (match_dup 4) - (unspec:SI [(const_int 0) - (match_operand:BLK 1 "memory_operand" "") - (reg:QI 0) - (match_operand 3 "immediate_operand" "")] UNSPEC_SRST)) - (clobber (scratch:SI)) - (clobber (reg:CC 33))]) +; +; cmpstrM instruction pattern(s). +; + +(define_expand "cmpstrsi" + [(set (reg:SI 0) (const_int 0)) (parallel - [(set (match_operand:SI 0 "register_operand" "") - (minus:SI (match_dup 4) (match_dup 5))) - (clobber (reg:CC 33))])] - "!TARGET_64BIT" + [(clobber (match_operand 3 "" "")) + (clobber (match_dup 4)) + (set (reg:CCU CC_REGNUM) + (compare:CCU (match_operand:BLK 1 "memory_operand" "") + (match_operand:BLK 2 "memory_operand" ""))) + (use (reg:SI 0))]) + (parallel + [(set (match_operand:SI 0 "register_operand" "=d") + (unspec:SI [(reg:CCU CC_REGNUM)] UNSPEC_CMPINT)) + (clobber (reg:CC CC_REGNUM))])] + "" { - operands[4] = gen_reg_rtx (SImode); - operands[5] = gen_reg_rtx (SImode); - emit_move_insn (operands[5], force_operand (XEXP (operands[1], 0), NULL_RTX)); - operands[1] = replace_equiv_address (operands[1], operands[5]); + /* As the result of CMPINT is inverted compared to what we need, + we have to swap the operands. */ + rtx op1 = operands[2]; + rtx op2 = operands[1]; + rtx addr1 = gen_reg_rtx (Pmode); + rtx addr2 = gen_reg_rtx (Pmode); + + emit_move_insn (addr1, force_operand (XEXP (op1, 0), NULL_RTX)); + emit_move_insn (addr2, force_operand (XEXP (op2, 0), NULL_RTX)); + operands[1] = replace_equiv_address_nv (op1, addr1); + operands[2] = replace_equiv_address_nv (op2, addr2); + operands[3] = addr1; + operands[4] = addr2; }) -(define_insn "*strlensi" - [(set (match_operand:SI 0 "register_operand" "=a") - (unspec:SI [(match_operand:SI 2 "general_operand" "0") - (mem:BLK (match_operand:SI 3 "register_operand" "1")) - (reg:QI 0) - (match_operand 4 "immediate_operand" "")] UNSPEC_SRST)) - (clobber (match_scratch:SI 1 "=a")) - (clobber (reg:CC 33))] - "!TARGET_64BIT" - "srst\t%0,%1\;jo\t.-4" - [(set_attr "op_type" "NN") - (set_attr "type" "vs") - (set_attr "length" "8")]) - +(define_insn "*cmpstr<mode>" + [(clobber (match_operand:P 0 "register_operand" "=d")) + (clobber (match_operand:P 1 "register_operand" "=d")) + (set (reg:CCU CC_REGNUM) + (compare:CCU (mem:BLK (match_operand:P 2 "register_operand" "0")) + (mem:BLK (match_operand:P 3 "register_operand" "1")))) + (use (reg:SI 0))] + "" + "clst\t%0,%1\;jo\t.-4" + [(set_attr "length" "8") + (set_attr "type" "vs")]) + ; -; movstrM instruction pattern(s). +; movstr instruction pattern. ; -(define_expand "movstrdi" - [(set (match_operand:BLK 0 "memory_operand" "") - (match_operand:BLK 1 "memory_operand" "")) - (use (match_operand:DI 2 "general_operand" "")) - (match_operand 3 "" "")] - "TARGET_64BIT" - "s390_expand_movstr (operands[0], operands[1], operands[2]); DONE;") +(define_expand "movstr" + [(set (reg:SI 0) (const_int 0)) + (parallel + [(clobber (match_dup 3)) + (set (match_operand:BLK 1 "memory_operand" "") + (match_operand:BLK 2 "memory_operand" "")) + (set (match_operand 0 "register_operand" "") + (unspec [(match_dup 1) + (match_dup 2) + (reg:SI 0)] UNSPEC_MVST)) + (clobber (reg:CC CC_REGNUM))])] + "" +{ + rtx addr1 = gen_reg_rtx (Pmode); + rtx addr2 = gen_reg_rtx (Pmode); + + emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX)); + emit_move_insn (addr2, force_operand (XEXP (operands[2], 0), NULL_RTX)); + operands[1] = replace_equiv_address_nv (operands[1], addr1); + operands[2] = replace_equiv_address_nv (operands[2], addr2); + operands[3] = addr2; +}) -(define_expand "movstrsi" +(define_insn "*movstr" + [(clobber (match_operand:P 2 "register_operand" "=d")) + (set (mem:BLK (match_operand:P 1 "register_operand" "0")) + (mem:BLK (match_operand:P 3 "register_operand" "2"))) + (set (match_operand:P 0 "register_operand" "=d") + (unspec [(mem:BLK (match_dup 1)) + (mem:BLK (match_dup 3)) + (reg:SI 0)] UNSPEC_MVST)) + (clobber (reg:CC CC_REGNUM))] + "" + "mvst\t%1,%2\;jo\t.-4" + [(set_attr "length" "8") + (set_attr "type" "vs")]) + + +; +; movmemM instruction pattern(s). +; + +(define_expand "movmem<mode>" [(set (match_operand:BLK 0 "memory_operand" "") (match_operand:BLK 1 "memory_operand" "")) - (use (match_operand:SI 2 "general_operand" "")) + (use (match_operand:GPR 2 "general_operand" "")) (match_operand 3 "" "")] "" - "s390_expand_movstr (operands[0], operands[1], operands[2]); DONE;") + "s390_expand_movmem (operands[0], operands[1], operands[2]); DONE;") ; Move a block that is up to 256 bytes in length. ; The block length is taken as (operands[2] % 256) + 1. -(define_expand "movstr_short" +(define_expand "movmem_short" [(parallel [(set (match_operand:BLK 0 "memory_operand" "") (match_operand:BLK 1 "memory_operand" "")) (use (match_operand 2 "nonmemory_operand" "")) + (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN))) (clobber (match_dup 3))])] "" "operands[3] = gen_rtx_SCRATCH (Pmode);") -(define_insn "*movstr_short" - [(set (match_operand:BLK 0 "memory_operand" "=Q,Q") - (match_operand:BLK 1 "memory_operand" "Q,Q")) - (use (match_operand 2 "nonmemory_operand" "n,a")) - (clobber (match_scratch 3 "=X,&a"))] +(define_insn "*movmem_short" + [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q") + (match_operand:BLK 1 "memory_operand" "Q,Q,Q")) + (use (match_operand 2 "nonmemory_operand" "n,a,a")) + (use (match_operand 3 "immediate_operand" "X,R,X")) + (clobber (match_scratch 4 "=X,X,&a"))] "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode) - && GET_MODE (operands[3]) == Pmode" -{ - switch (which_alternative) - { - case 0: - return "mvc\t%O0(%b2+1,%R0),%1"; + && GET_MODE (operands[4]) == Pmode" + "#" + [(set_attr "type" "cs")]) - case 1: - output_asm_insn ("bras\t%3,.+10", operands); - output_asm_insn ("mvc\t%O0(1,%R0),%1", operands); - return "ex\t%2,0(%3)"; +(define_split + [(set (match_operand:BLK 0 "memory_operand" "") + (match_operand:BLK 1 "memory_operand" "")) + (use (match_operand 2 "const_int_operand" "")) + (use (match_operand 3 "immediate_operand" "")) + (clobber (scratch))] + "reload_completed" + [(parallel + [(set (match_dup 0) (match_dup 1)) + (use (match_dup 2))])] + "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);") - default: - abort (); - } -} - [(set_attr "op_type" "SS,NN") - (set_attr "type" "cs,cs") - (set_attr "atype" "*,agen") - (set_attr "length" "*,14")]) +(define_split + [(set (match_operand:BLK 0 "memory_operand" "") + (match_operand:BLK 1 "memory_operand" "")) + (use (match_operand 2 "register_operand" "")) + (use (match_operand 3 "memory_operand" "")) + (clobber (scratch))] + "reload_completed" + [(parallel + [(unspec [(match_dup 2) (match_dup 3) + (const_int 0)] UNSPEC_EXECUTE) + (set (match_dup 0) (match_dup 1)) + (use (const_int 1))])] + "") + +(define_split + [(set (match_operand:BLK 0 "memory_operand" "") + (match_operand:BLK 1 "memory_operand" "")) + (use (match_operand 2 "register_operand" "")) + (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN))) + (clobber (match_operand 3 "register_operand" ""))] + "reload_completed && TARGET_CPU_ZARCH" + [(set (match_dup 3) (label_ref (match_dup 4))) + (parallel + [(unspec [(match_dup 2) (mem:BLK (match_dup 3)) + (label_ref (match_dup 4))] UNSPEC_EXECUTE) + (set (match_dup 0) (match_dup 1)) + (use (const_int 1))])] + "operands[4] = gen_label_rtx ();") ; Move a block of arbitrary length. -(define_expand "movstr_long" +(define_expand "movmem_long" [(parallel [(clobber (match_dup 2)) (clobber (match_dup 3)) @@ -2038,7 +2176,7 @@ (match_operand:BLK 1 "memory_operand" "")) (use (match_operand 2 "general_operand" "")) (use (match_dup 3)) - (clobber (reg:CC 33))])] + (clobber (reg:CC CC_REGNUM))])] "" { enum machine_mode dword_mode = word_mode == DImode ? TImode : DImode; @@ -2063,105 +2201,114 @@ operands[3] = reg1; }) -(define_insn "*movstr_long_64" - [(clobber (match_operand:TI 0 "register_operand" "=d")) - (clobber (match_operand:TI 1 "register_operand" "=d")) - (set (mem:BLK (subreg:DI (match_operand:TI 2 "register_operand" "0") 0)) - (mem:BLK (subreg:DI (match_operand:TI 3 "register_operand" "1") 0))) - (use (match_dup 2)) - (use (match_dup 3)) - (clobber (reg:CC 33))] - "TARGET_64BIT" - "mvcle\t%0,%1,0\;jo\t.-4" - [(set_attr "op_type" "NN") - (set_attr "type" "vs") - (set_attr "length" "8")]) - -(define_insn "*movstr_long_31" - [(clobber (match_operand:DI 0 "register_operand" "=d")) - (clobber (match_operand:DI 1 "register_operand" "=d")) - (set (mem:BLK (subreg:SI (match_operand:DI 2 "register_operand" "0") 0)) - (mem:BLK (subreg:SI (match_operand:DI 3 "register_operand" "1") 0))) +(define_insn "*movmem_long" + [(clobber (match_operand:<DBL> 0 "register_operand" "=d")) + (clobber (match_operand:<DBL> 1 "register_operand" "=d")) + (set (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0)) + (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0))) (use (match_dup 2)) (use (match_dup 3)) - (clobber (reg:CC 33))] - "!TARGET_64BIT" + (clobber (reg:CC CC_REGNUM))] + "" "mvcle\t%0,%1,0\;jo\t.-4" - [(set_attr "op_type" "NN") - (set_attr "type" "vs") - (set_attr "length" "8")]) + [(set_attr "length" "8") + (set_attr "type" "vs")]) ; -; clrstrM instruction pattern(s). +; setmemM instruction pattern(s). ; -(define_expand "clrstrdi" +(define_expand "setmem<mode>" [(set (match_operand:BLK 0 "memory_operand" "") - (const_int 0)) - (use (match_operand:DI 1 "general_operand" "")) - (match_operand 2 "" "")] - "TARGET_64BIT" - "s390_expand_clrstr (operands[0], operands[1]); DONE;") - -(define_expand "clrstrsi" - [(set (match_operand:BLK 0 "memory_operand" "") - (const_int 0)) - (use (match_operand:SI 1 "general_operand" "")) - (match_operand 2 "" "")] + (match_operand:QI 2 "general_operand" "")) + (use (match_operand:GPR 1 "general_operand" "")) + (match_operand 3 "" "")] "" - "s390_expand_clrstr (operands[0], operands[1]); DONE;") + "s390_expand_setmem (operands[0], operands[1], operands[2]); DONE;") ; Clear a block that is up to 256 bytes in length. ; The block length is taken as (operands[1] % 256) + 1. -(define_expand "clrstr_short" +(define_expand "clrmem_short" [(parallel [(set (match_operand:BLK 0 "memory_operand" "") (const_int 0)) (use (match_operand 1 "nonmemory_operand" "")) + (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN))) (clobber (match_dup 2)) - (clobber (reg:CC 33))])] + (clobber (reg:CC CC_REGNUM))])] "" "operands[2] = gen_rtx_SCRATCH (Pmode);") -(define_insn "*clrstr_short" - [(set (match_operand:BLK 0 "memory_operand" "=Q,Q") +(define_insn "*clrmem_short" + [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q") (const_int 0)) - (use (match_operand 1 "nonmemory_operand" "n,a")) - (clobber (match_scratch 2 "=X,&a")) - (clobber (reg:CC 33))] + (use (match_operand 1 "nonmemory_operand" "n,a,a")) + (use (match_operand 2 "immediate_operand" "X,R,X")) + (clobber (match_scratch 3 "=X,X,&a")) + (clobber (reg:CC CC_REGNUM))] "(GET_MODE (operands[1]) == Pmode || GET_MODE (operands[1]) == VOIDmode) - && GET_MODE (operands[2]) == Pmode" -{ - switch (which_alternative) - { - case 0: - return "xc\t%O0(%b1+1,%R0),%0"; + && GET_MODE (operands[3]) == Pmode" + "#" + [(set_attr "type" "cs")]) + +(define_split + [(set (match_operand:BLK 0 "memory_operand" "") + (const_int 0)) + (use (match_operand 1 "const_int_operand" "")) + (use (match_operand 2 "immediate_operand" "")) + (clobber (scratch)) + (clobber (reg:CC CC_REGNUM))] + "reload_completed" + [(parallel + [(set (match_dup 0) (const_int 0)) + (use (match_dup 1)) + (clobber (reg:CC CC_REGNUM))])] + "operands[1] = GEN_INT ((INTVAL (operands[1]) & 0xff) + 1);") - case 1: - output_asm_insn ("bras\t%2,.+10", operands); - output_asm_insn ("xc\t%O0(1,%R0),%0", operands); - return "ex\t%1,0(%2)"; +(define_split + [(set (match_operand:BLK 0 "memory_operand" "") + (const_int 0)) + (use (match_operand 1 "register_operand" "")) + (use (match_operand 2 "memory_operand" "")) + (clobber (scratch)) + (clobber (reg:CC CC_REGNUM))] + "reload_completed" + [(parallel + [(unspec [(match_dup 1) (match_dup 2) + (const_int 0)] UNSPEC_EXECUTE) + (set (match_dup 0) (const_int 0)) + (use (const_int 1)) + (clobber (reg:CC CC_REGNUM))])] + "") - default: - abort (); - } -} - [(set_attr "op_type" "SS,NN") - (set_attr "type" "cs,cs") - (set_attr "atype" "*,agen") - (set_attr "length" "*,14")]) +(define_split + [(set (match_operand:BLK 0 "memory_operand" "") + (const_int 0)) + (use (match_operand 1 "register_operand" "")) + (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN))) + (clobber (match_operand 2 "register_operand" "")) + (clobber (reg:CC CC_REGNUM))] + "reload_completed && TARGET_CPU_ZARCH" + [(set (match_dup 2) (label_ref (match_dup 3))) + (parallel + [(unspec [(match_dup 1) (mem:BLK (match_dup 2)) + (label_ref (match_dup 3))] UNSPEC_EXECUTE) + (set (match_dup 0) (const_int 0)) + (use (const_int 1)) + (clobber (reg:CC CC_REGNUM))])] + "operands[3] = gen_label_rtx ();") -; Clear a block of arbitrary length. +; Initialize a block of arbitrary length with (operands[2] % 256). -(define_expand "clrstr_long" +(define_expand "setmem_long" [(parallel [(clobber (match_dup 1)) (set (match_operand:BLK 0 "memory_operand" "") - (const_int 0)) + (match_operand 2 "shift_count_or_setmem_operand" "")) (use (match_operand 1 "general_operand" "")) - (use (match_dup 2)) - (clobber (reg:CC 33))])] + (use (match_dup 3)) + (clobber (reg:CC CC_REGNUM))])] "" { enum machine_mode dword_mode = word_mode == DImode ? TImode : DImode; @@ -2178,49 +2325,37 @@ operands[0] = replace_equiv_address_nv (operands[0], addr0); operands[1] = reg0; - operands[2] = reg1; + operands[3] = reg1; }) -(define_insn "*clrstr_long_64" - [(clobber (match_operand:TI 0 "register_operand" "=d")) - (set (mem:BLK (subreg:DI (match_operand:TI 2 "register_operand" "0") 0)) - (const_int 0)) - (use (match_dup 2)) - (use (match_operand:TI 1 "register_operand" "d")) - (clobber (reg:CC 33))] - "TARGET_64BIT" - "mvcle\t%0,%1,0\;jo\t.-4" - [(set_attr "op_type" "NN") - (set_attr "type" "vs") - (set_attr "length" "8")]) - -(define_insn "*clrstr_long_31" - [(clobber (match_operand:DI 0 "register_operand" "=d")) - (set (mem:BLK (subreg:SI (match_operand:DI 2 "register_operand" "0") 0)) - (const_int 0)) - (use (match_dup 2)) - (use (match_operand:DI 1 "register_operand" "d")) - (clobber (reg:CC 33))] - "!TARGET_64BIT" - "mvcle\t%0,%1,0\;jo\t.-4" - [(set_attr "op_type" "NN") - (set_attr "type" "vs") - (set_attr "length" "8")]) - +(define_insn "*setmem_long" + [(clobber (match_operand:<DBL> 0 "register_operand" "=d")) + (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0)) + (match_operand 2 "shift_count_or_setmem_operand" "Y")) + (use (match_dup 3)) + (use (match_operand:<DBL> 1 "register_operand" "d")) + (clobber (reg:CC CC_REGNUM))] + "" + "mvcle\t%0,%1,%Y2\;jo\t.-4" + [(set_attr "length" "8") + (set_attr "type" "vs")]) + +(define_insn "*setmem_long_and" + [(clobber (match_operand:<DBL> 0 "register_operand" "=d")) + (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0)) + (and (match_operand 2 "shift_count_or_setmem_operand" "Y") + (match_operand 4 "const_int_operand" "n"))) + (use (match_dup 3)) + (use (match_operand:<DBL> 1 "register_operand" "d")) + (clobber (reg:CC CC_REGNUM))] + "(INTVAL (operands[4]) & 255) == 255" + "mvcle\t%0,%1,%Y2\;jo\t.-4" + [(set_attr "length" "8") + (set_attr "type" "vs")]) ; ; cmpmemM instruction pattern(s). ; -(define_expand "cmpmemdi" - [(set (match_operand:DI 0 "register_operand" "") - (compare:DI (match_operand:BLK 1 "memory_operand" "") - (match_operand:BLK 2 "memory_operand" "") ) ) - (use (match_operand:DI 3 "general_operand" "")) - (use (match_operand:DI 4 "" ""))] - "TARGET_64BIT" - "s390_expand_cmpmem (operands[0], operands[1], - operands[2], operands[3]); DONE;") - (define_expand "cmpmemsi" [(set (match_operand:SI 0 "register_operand" "") (compare:SI (match_operand:BLK 1 "memory_operand" "") @@ -2236,41 +2371,70 @@ (define_expand "cmpmem_short" [(parallel - [(set (reg:CCS 33) - (compare:CCS (match_operand:BLK 0 "memory_operand" "") + [(set (reg:CCU CC_REGNUM) + (compare:CCU (match_operand:BLK 0 "memory_operand" "") (match_operand:BLK 1 "memory_operand" ""))) (use (match_operand 2 "nonmemory_operand" "")) + (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN))) (clobber (match_dup 3))])] "" "operands[3] = gen_rtx_SCRATCH (Pmode);") (define_insn "*cmpmem_short" - [(set (reg:CCS 33) - (compare:CCS (match_operand:BLK 0 "memory_operand" "=Q,Q") - (match_operand:BLK 1 "memory_operand" "Q,Q"))) - (use (match_operand 2 "nonmemory_operand" "n,a")) - (clobber (match_scratch 3 "=X,&a"))] + [(set (reg:CCU CC_REGNUM) + (compare:CCU (match_operand:BLK 0 "memory_operand" "Q,Q,Q") + (match_operand:BLK 1 "memory_operand" "Q,Q,Q"))) + (use (match_operand 2 "nonmemory_operand" "n,a,a")) + (use (match_operand 3 "immediate_operand" "X,R,X")) + (clobber (match_scratch 4 "=X,X,&a"))] "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode) - && GET_MODE (operands[3]) == Pmode" -{ - switch (which_alternative) - { - case 0: - return "clc\t%O0(%b2+1,%R0),%1"; + && GET_MODE (operands[4]) == Pmode" + "#" + [(set_attr "type" "cs")]) - case 1: - output_asm_insn ("bras\t%3,.+10", operands); - output_asm_insn ("clc\t%O0(1,%R0),%1", operands); - return "ex\t%2,0(%3)"; +(define_split + [(set (reg:CCU CC_REGNUM) + (compare:CCU (match_operand:BLK 0 "memory_operand" "") + (match_operand:BLK 1 "memory_operand" ""))) + (use (match_operand 2 "const_int_operand" "")) + (use (match_operand 3 "immediate_operand" "")) + (clobber (scratch))] + "reload_completed" + [(parallel + [(set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1))) + (use (match_dup 2))])] + "operands[2] = GEN_INT ((INTVAL (operands[2]) & 0xff) + 1);") - default: - abort (); - } -} - [(set_attr "op_type" "SS,NN") - (set_attr "type" "cs,cs") - (set_attr "atype" "*,agen") - (set_attr "length" "*,14")]) +(define_split + [(set (reg:CCU CC_REGNUM) + (compare:CCU (match_operand:BLK 0 "memory_operand" "") + (match_operand:BLK 1 "memory_operand" ""))) + (use (match_operand 2 "register_operand" "")) + (use (match_operand 3 "memory_operand" "")) + (clobber (scratch))] + "reload_completed" + [(parallel + [(unspec [(match_dup 2) (match_dup 3) + (const_int 0)] UNSPEC_EXECUTE) + (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1))) + (use (const_int 1))])] + "") + +(define_split + [(set (reg:CCU CC_REGNUM) + (compare:CCU (match_operand:BLK 0 "memory_operand" "") + (match_operand:BLK 1 "memory_operand" ""))) + (use (match_operand 2 "register_operand" "")) + (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN))) + (clobber (match_operand 3 "register_operand" ""))] + "reload_completed && TARGET_CPU_ZARCH" + [(set (match_dup 3) (label_ref (match_dup 4))) + (parallel + [(unspec [(match_dup 2) (mem:BLK (match_dup 3)) + (label_ref (match_dup 4))] UNSPEC_EXECUTE) + (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1))) + (use (const_int 1))])] + "operands[4] = gen_label_rtx ();") ; Compare a block of arbitrary length. @@ -2278,8 +2442,8 @@ [(parallel [(clobber (match_dup 2)) (clobber (match_dup 3)) - (set (reg:CCS 33) - (compare:CCS (match_operand:BLK 0 "memory_operand" "") + (set (reg:CCU CC_REGNUM) + (compare:CCU (match_operand:BLK 0 "memory_operand" "") (match_operand:BLK 1 "memory_operand" ""))) (use (match_operand 2 "general_operand" "")) (use (match_dup 3))])] @@ -2307,148 +2471,268 @@ operands[3] = reg1; }) -(define_insn "*cmpmem_long_64" - [(clobber (match_operand:TI 0 "register_operand" "=d")) - (clobber (match_operand:TI 1 "register_operand" "=d")) - (set (reg:CCS 33) - (compare:CCS (mem:BLK (subreg:DI (match_operand:TI 2 "register_operand" "0") 0)) - (mem:BLK (subreg:DI (match_operand:TI 3 "register_operand" "1") 0)))) - (use (match_dup 2)) - (use (match_dup 3))] - "TARGET_64BIT" - "clcle\t%0,%1,0\;jo\t.-4" - [(set_attr "op_type" "NN") - (set_attr "type" "vs") - (set_attr "length" "8")]) - -(define_insn "*cmpmem_long_31" - [(clobber (match_operand:DI 0 "register_operand" "=d")) - (clobber (match_operand:DI 1 "register_operand" "=d")) - (set (reg:CCS 33) - (compare:CCS (mem:BLK (subreg:SI (match_operand:DI 2 "register_operand" "0") 0)) - (mem:BLK (subreg:SI (match_operand:DI 3 "register_operand" "1") 0)))) +(define_insn "*cmpmem_long" + [(clobber (match_operand:<DBL> 0 "register_operand" "=d")) + (clobber (match_operand:<DBL> 1 "register_operand" "=d")) + (set (reg:CCU CC_REGNUM) + (compare:CCU (mem:BLK (subreg:P (match_operand:<DBL> 2 "register_operand" "0") 0)) + (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "1") 0)))) (use (match_dup 2)) (use (match_dup 3))] - "!TARGET_64BIT" + "" "clcle\t%0,%1,0\;jo\t.-4" - [(set_attr "op_type" "NN") - (set_attr "type" "vs") - (set_attr "length" "8")]) + [(set_attr "length" "8") + (set_attr "type" "vs")]) -; Convert condition code to integer in range (-1, 0, 1) +; Convert CCUmode condition code to integer. +; Result is zero if EQ, positive if LTU, negative if GTU. -(define_insn "cmpint_si" +(define_insn_and_split "cmpint" [(set (match_operand:SI 0 "register_operand" "=d") - (compare:SI (reg:CCS 33) (const_int 0)))] + (unspec:SI [(match_operand:CCU 1 "register_operand" "0")] + UNSPEC_CMPINT)) + (clobber (reg:CC CC_REGNUM))] "" + "#" + "reload_completed" + [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2))) + (parallel + [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30))) + (clobber (reg:CC CC_REGNUM))])]) + +(define_insn_and_split "*cmpint_cc" + [(set (reg CC_REGNUM) + (compare (unspec:SI [(match_operand:CCU 1 "register_operand" "0")] + UNSPEC_CMPINT) + (const_int 0))) + (set (match_operand:SI 0 "register_operand" "=d") + (unspec:SI [(match_dup 1)] UNSPEC_CMPINT))] + "s390_match_ccmode (insn, CCSmode)" + "#" + "&& reload_completed" + [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2))) + (parallel + [(set (match_dup 2) (match_dup 3)) + (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))])] { - output_asm_insn ("lhi\t%0,1", operands); - output_asm_insn ("jh\t.+12", operands); - output_asm_insn ("jl\t.+6", operands); - output_asm_insn ("sr\t%0,%0", operands); - return "lcr\t%0,%0"; -} - [(set_attr "op_type" "NN") - (set_attr "length" "16") - (set_attr "type" "other")]) + rtx result = gen_rtx_ASHIFTRT (SImode, operands[0], GEN_INT (30)); + operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0)); + operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx); +}) -(define_insn "cmpint_di" +(define_insn_and_split "*cmpint_sign" [(set (match_operand:DI 0 "register_operand" "=d") - (compare:DI (reg:CCS 33) (const_int 0)))] + (sign_extend:DI (unspec:SI [(match_operand:CCU 1 "register_operand" "0")] + UNSPEC_CMPINT))) + (clobber (reg:CC CC_REGNUM))] "TARGET_64BIT" + "#" + "&& reload_completed" + [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34))) + (parallel + [(set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62))) + (clobber (reg:CC CC_REGNUM))])]) + +(define_insn_and_split "*cmpint_sign_cc" + [(set (reg CC_REGNUM) + (compare (ashiftrt:DI (ashift:DI (subreg:DI + (unspec:SI [(match_operand:CCU 1 "register_operand" "0")] + UNSPEC_CMPINT) 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)))] + "s390_match_ccmode (insn, CCSmode) && TARGET_64BIT" + "#" + "&& reload_completed" + [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34))) + (parallel + [(set (match_dup 2) (match_dup 3)) + (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))])] { - output_asm_insn ("lghi\t%0,1", operands); - output_asm_insn ("jh\t.+16", operands); - output_asm_insn ("jl\t.+8", operands); - output_asm_insn ("sgr\t%0,%0", operands); - return "lcgr\t%0,%0"; -} - [(set_attr "op_type" "NN") - (set_attr "length" "20") - (set_attr "type" "other")]) + rtx result = gen_rtx_ASHIFTRT (DImode, operands[0], GEN_INT (62)); + operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0)); + operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx); +}) ;; ;;- Conversion instructions. ;; -(define_insn "*sethighqisi" - [(set (match_operand:SI 0 "register_operand" "=d,d") - (unspec:SI [(match_operand:QI 1 "s_operand" "Q,S")] UNSPEC_SETHIGH)) - (clobber (reg:CC 33))] - "" - "@ - icm\t%0,8,%1 - icmy\t%0,8,%1" - [(set_attr "op_type" "RS,RSY")]) - -(define_insn "*sethighhisi" +(define_insn "*sethighpartsi" [(set (match_operand:SI 0 "register_operand" "=d,d") - (unspec:SI [(match_operand:HI 1 "s_operand" "Q,S")] UNSPEC_SETHIGH)) - (clobber (reg:CC 33))] + (unspec:SI [(match_operand:BLK 1 "s_operand" "Q,S") + (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM)) + (clobber (reg:CC CC_REGNUM))] "" "@ - icm\t%0,12,%1 - icmy\t%0,12,%1" + icm\t%0,%2,%S1 + icmy\t%0,%2,%S1" [(set_attr "op_type" "RS,RSY")]) -(define_insn "*sethighqidi_64" +(define_insn "*sethighpartdi_64" [(set (match_operand:DI 0 "register_operand" "=d") - (unspec:DI [(match_operand:QI 1 "s_operand" "QS")] UNSPEC_SETHIGH)) - (clobber (reg:CC 33))] + (unspec:DI [(match_operand:BLK 1 "s_operand" "QS") + (match_operand 2 "const_int_operand" "n")] UNSPEC_ICM)) + (clobber (reg:CC CC_REGNUM))] "TARGET_64BIT" - "icmh\t%0,8,%1" + "icmh\t%0,%2,%S1" [(set_attr "op_type" "RSY")]) -(define_insn "*sethighqidi_31" +(define_insn "*sethighpartdi_31" [(set (match_operand:DI 0 "register_operand" "=d,d") - (unspec:DI [(match_operand:QI 1 "s_operand" "Q,S")] UNSPEC_SETHIGH)) - (clobber (reg:CC 33))] + (unspec:DI [(match_operand:BLK 1 "s_operand" "Q,S") + (match_operand 2 "const_int_operand" "n,n")] UNSPEC_ICM)) + (clobber (reg:CC CC_REGNUM))] "!TARGET_64BIT" "@ - icm\t%0,8,%1 - icmy\t%0,8,%1" + icm\t%0,%2,%S1 + icmy\t%0,%2,%S1" [(set_attr "op_type" "RS,RSY")]) -(define_insn_and_split "*extractqi" - [(set (match_operand:SI 0 "register_operand" "=d") - (zero_extract:SI (match_operand:QI 1 "s_operand" "Q") - (match_operand 2 "const_int_operand" "n") - (const_int 0))) - (clobber (reg:CC 33))] - "!TARGET_64BIT - && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 8" +(define_insn_and_split "*extzv<mode>" + [(set (match_operand:GPR 0 "register_operand" "=d") + (zero_extract:GPR (match_operand:QI 1 "s_operand" "QS") + (match_operand 2 "const_int_operand" "n") + (const_int 0))) + (clobber (reg:CC CC_REGNUM))] + "INTVAL (operands[2]) > 0 + && INTVAL (operands[2]) <= GET_MODE_BITSIZE (SImode)" "#" "&& reload_completed" [(parallel - [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_SETHIGH)) - (clobber (reg:CC 33))]) - (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))] + [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM)) + (clobber (reg:CC CC_REGNUM))]) + (set (match_dup 0) (lshiftrt:GPR (match_dup 0) (match_dup 2)))] { - operands[2] = GEN_INT (32 - INTVAL (operands[2])); - operands[1] = change_address (operands[1], QImode, 0); -} - [(set_attr "atype" "agen")]) + int bitsize = INTVAL (operands[2]); + int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */ + int mask = ((1ul << size) - 1) << (GET_MODE_SIZE (SImode) - size); + + operands[1] = adjust_address (operands[1], BLKmode, 0); + set_mem_size (operands[1], GEN_INT (size)); + operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - bitsize); + operands[3] = GEN_INT (mask); +}) -(define_insn_and_split "*extracthi" - [(set (match_operand:SI 0 "register_operand" "=d") - (zero_extract:SI (match_operand:QI 1 "s_operand" "Q") - (match_operand 2 "const_int_operand" "n") - (const_int 0))) - (clobber (reg:CC 33))] - "!TARGET_64BIT - && INTVAL (operands[2]) >= 8 && INTVAL (operands[2]) < 16" +(define_insn_and_split "*extv<mode>" + [(set (match_operand:GPR 0 "register_operand" "=d") + (sign_extract:GPR (match_operand:QI 1 "s_operand" "QS") + (match_operand 2 "const_int_operand" "n") + (const_int 0))) + (clobber (reg:CC CC_REGNUM))] + "INTVAL (operands[2]) > 0 + && INTVAL (operands[2]) <= GET_MODE_BITSIZE (SImode)" "#" "&& reload_completed" [(parallel - [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_SETHIGH)) - (clobber (reg:CC 33))]) - (set (match_dup 0) (lshiftrt:SI (match_dup 0) (match_dup 2)))] + [(set (match_dup 0) (unspec:GPR [(match_dup 1) (match_dup 3)] UNSPEC_ICM)) + (clobber (reg:CC CC_REGNUM))]) + (parallel + [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2))) + (clobber (reg:CC CC_REGNUM))])] { - operands[2] = GEN_INT (32 - INTVAL (operands[2])); - operands[1] = change_address (operands[1], HImode, 0); + int bitsize = INTVAL (operands[2]); + int size = (bitsize - 1) / BITS_PER_UNIT + 1; /* round up */ + int mask = ((1ul << size) - 1) << (GET_MODE_SIZE (SImode) - size); + + operands[1] = adjust_address (operands[1], BLKmode, 0); + set_mem_size (operands[1], GEN_INT (size)); + operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - bitsize); + operands[3] = GEN_INT (mask); +}) + +; +; insv instruction patterns +; + +(define_expand "insv" + [(set (zero_extract (match_operand 0 "nonimmediate_operand" "") + (match_operand 1 "const_int_operand" "") + (match_operand 2 "const_int_operand" "")) + (match_operand 3 "general_operand" ""))] + "" +{ + if (s390_expand_insv (operands[0], operands[1], operands[2], operands[3])) + DONE; + FAIL; +}) + +(define_insn "*insv<mode>_mem_reg" + [(set (zero_extract:P (match_operand:QI 0 "memory_operand" "+Q,S") + (match_operand 1 "const_int_operand" "n,n") + (const_int 0)) + (match_operand:P 2 "register_operand" "d,d"))] + "INTVAL (operands[1]) > 0 + && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode) + && INTVAL (operands[1]) % BITS_PER_UNIT == 0" +{ + int size = INTVAL (operands[1]) / BITS_PER_UNIT; + + operands[1] = GEN_INT ((1ul << size) - 1); + return (which_alternative == 0) ? "stcm\t%2,%1,%S0" + : "stcmy\t%2,%1,%S0"; } - [(set_attr "atype" "agen")]) + [(set_attr "op_type" "RS,RSY")]) + +(define_insn "*insvdi_mem_reghigh" + [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "+QS") + (match_operand 1 "const_int_operand" "n") + (const_int 0)) + (lshiftrt:DI (match_operand:DI 2 "register_operand" "d") + (const_int 32)))] + "TARGET_64BIT + && INTVAL (operands[1]) > 0 + && INTVAL (operands[1]) <= GET_MODE_BITSIZE (SImode) + && INTVAL (operands[1]) % BITS_PER_UNIT == 0" +{ + int size = INTVAL (operands[1]) / BITS_PER_UNIT; + + operands[1] = GEN_INT ((1ul << size) - 1); + return "stcmh\t%2,%1,%S0"; +} +[(set_attr "op_type" "RSY")]) + +(define_insn "*insv<mode>_reg_imm" + [(set (zero_extract:P (match_operand:P 0 "register_operand" "+d") + (const_int 16) + (match_operand 1 "const_int_operand" "n")) + (match_operand:P 2 "const_int_operand" "n"))] + "TARGET_ZARCH + && INTVAL (operands[1]) >= 0 + && INTVAL (operands[1]) < BITS_PER_WORD + && INTVAL (operands[1]) % 16 == 0" +{ + switch (BITS_PER_WORD - INTVAL (operands[1])) + { + case 64: return "iihh\t%0,%x2"; break; + case 48: return "iihl\t%0,%x2"; break; + case 32: return "iilh\t%0,%x2"; break; + case 16: return "iill\t%0,%x2"; break; + default: gcc_unreachable(); + } +} + [(set_attr "op_type" "RI")]) + +(define_insn "*insv<mode>_reg_extimm" + [(set (zero_extract:P (match_operand:P 0 "register_operand" "+d") + (const_int 32) + (match_operand 1 "const_int_operand" "n")) + (match_operand:P 2 "const_int_operand" "n"))] + "TARGET_EXTIMM + && INTVAL (operands[1]) >= 0 + && INTVAL (operands[1]) < BITS_PER_WORD + && INTVAL (operands[1]) % 32 == 0" +{ + switch (BITS_PER_WORD - INTVAL (operands[1])) + { + case 64: return "iihf\t%0,%o2"; break; + case 32: return "iilf\t%0,%o2"; break; + default: gcc_unreachable(); + } +} + [(set_attr "op_type" "RIL")]) ; ; extendsidi2 instruction pattern(s). @@ -2458,7 +2742,6 @@ [(set (match_operand:DI 0 "register_operand" "") (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))] "" - " { if (!TARGET_64BIT) { @@ -2468,8 +2751,7 @@ emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (32))); DONE; } -} -") +}) (define_insn "*extendsidi2" [(set (match_operand:DI 0 "register_operand" "=d,d") @@ -2481,31 +2763,45 @@ [(set_attr "op_type" "RRE,RXY")]) ; -; extendhidi2 instruction pattern(s). +; extend(hi|qi)(si|di)2 instruction pattern(s). ; -(define_expand "extendhidi2" - [(set (match_operand:DI 0 "register_operand" "") - (sign_extend:DI (match_operand:HI 1 "register_operand" "")))] +(define_expand "extend<HQI:mode><DSI:mode>2" + [(set (match_operand:DSI 0 "register_operand" "") + (sign_extend:DSI (match_operand:HQI 1 "nonimmediate_operand" "")))] "" - " { - if (!TARGET_64BIT) + if (<DSI:MODE>mode == DImode && !TARGET_64BIT) { rtx tmp = gen_reg_rtx (SImode); - emit_insn (gen_extendhisi2 (tmp, operands[1])); + emit_insn (gen_extend<HQI:mode>si2 (tmp, operands[1])); emit_insn (gen_extendsidi2 (operands[0], tmp)); DONE; } - else + else if (!TARGET_EXTIMM) { - operands[1] = gen_lowpart (DImode, operands[1]); - emit_insn (gen_ashldi3 (operands[0], operands[1], GEN_INT (48))); - emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (48))); + rtx bitcount = GEN_INT (GET_MODE_BITSIZE (<DSI:MODE>mode) - + GET_MODE_BITSIZE (<HQI:MODE>mode)); + + operands[1] = gen_lowpart (<DSI:MODE>mode, operands[1]); + emit_insn (gen_ashl<DSI:mode>3 (operands[0], operands[1], bitcount)); + emit_insn (gen_ashr<DSI:mode>3 (operands[0], operands[0], bitcount)); DONE; } -} -") +}) + +; +; extendhidi2 instruction pattern(s). +; + +(define_insn "*extendhidi2_extimm" + [(set (match_operand:DI 0 "register_operand" "=d,d") + (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))] + "TARGET_64BIT && TARGET_EXTIMM" + "@ + lghr\t%0,%1 + lgh\t%0,%1" + [(set_attr "op_type" "RRE,RXY")]) (define_insn "*extendhidi2" [(set (match_operand:DI 0 "register_operand" "=d") @@ -2515,123 +2811,69 @@ [(set_attr "op_type" "RXY")]) ; -; extendqidi2 instruction pattern(s). -; - -(define_expand "extendqidi2" - [(set (match_operand:DI 0 "register_operand" "") - (sign_extend:DI (match_operand:QI 1 "register_operand" "")))] - "" - " -{ - if (!TARGET_64BIT) - { - rtx tmp = gen_reg_rtx (SImode); - emit_insn (gen_extendqisi2 (tmp, operands[1])); - emit_insn (gen_extendsidi2 (operands[0], tmp)); - DONE; - } - else - { - operands[1] = gen_lowpart (DImode, operands[1]); - emit_insn (gen_ashldi3 (operands[0], operands[1], GEN_INT (56))); - emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (56))); - DONE; - } -} -") - -(define_insn "*extendqidi2" - [(set (match_operand:DI 0 "register_operand" "=d") - (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))] - "TARGET_64BIT && TARGET_LONG_DISPLACEMENT" - "lgb\t%0,%1" - [(set_attr "op_type" "RXY")]) - -(define_insn_and_split "*extendqidi2_short_displ" - [(set (match_operand:DI 0 "register_operand" "=d") - (sign_extend:DI (match_operand:QI 1 "s_operand" "Q"))) - (clobber (reg:CC 33))] - "TARGET_64BIT && !TARGET_LONG_DISPLACEMENT" - "#" - "&& reload_completed" - [(parallel - [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_SETHIGH)) - (clobber (reg:CC 33))]) - (parallel - [(set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 56))) - (clobber (reg:CC 33))])] - "") - -; ; extendhisi2 instruction pattern(s). ; -(define_expand "extendhisi2" - [(set (match_operand:SI 0 "register_operand" "") - (sign_extend:SI (match_operand:HI 1 "register_operand" "")))] - "" - " -{ - operands[1] = gen_lowpart (SImode, operands[1]); - emit_insn (gen_ashlsi3 (operands[0], operands[1], GEN_INT (16))); - emit_insn (gen_ashrsi3 (operands[0], operands[0], GEN_INT (16))); - DONE; -} -") +(define_insn "*extendhisi2_extimm" + [(set (match_operand:SI 0 "register_operand" "=d,d,d") + (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,T")))] + "TARGET_EXTIMM" + "@ + lhr\t%0,%1 + lh\t%0,%1 + lhy\t%0,%1" + [(set_attr "op_type" "RRE,RX,RXY")]) (define_insn "*extendhisi2" [(set (match_operand:SI 0 "register_operand" "=d,d") (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T")))] - "" + "!TARGET_EXTIMM" "@ lh\t%0,%1 lhy\t%0,%1" [(set_attr "op_type" "RX,RXY")]) ; -; extendqisi2 instruction pattern(s). +; extendqi(si|di)2 instruction pattern(s). ; -(define_expand "extendqisi2" - [(set (match_operand:SI 0 "register_operand" "") - (sign_extend:SI (match_operand:QI 1 "register_operand" "")))] - "" - " -{ - operands[1] = gen_lowpart (SImode, operands[1]); - emit_insn (gen_ashlsi3 (operands[0], operands[1], GEN_INT (24))); - emit_insn (gen_ashrsi3 (operands[0], operands[0], GEN_INT (24))); - DONE; -} -") +; lbr, lgbr, lb, lgb +(define_insn "*extendqi<mode>2_extimm" + [(set (match_operand:GPR 0 "register_operand" "=d,d") + (sign_extend:GPR (match_operand:QI 1 "nonimmediate_operand" "d,m")))] + "TARGET_EXTIMM" + "@ + l<g>br\t%0,%1 + l<g>b\t%0,%1" + [(set_attr "op_type" "RRE,RXY")]) -(define_insn "*extendqisi2" - [(set (match_operand:SI 0 "register_operand" "=d") - (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))] - "TARGET_LONG_DISPLACEMENT" - "lb\t%0,%1" +; lb, lgb +(define_insn "*extendqi<mode>2" + [(set (match_operand:GPR 0 "register_operand" "=d") + (sign_extend:GPR (match_operand:QI 1 "memory_operand" "m")))] + "!TARGET_EXTIMM && TARGET_LONG_DISPLACEMENT" + "l<g>b\t%0,%1" [(set_attr "op_type" "RXY")]) -(define_insn_and_split "*extendsiqi2_short_displ" - [(set (match_operand:SI 0 "register_operand" "=d") - (sign_extend:SI (match_operand:QI 1 "s_operand" "Q"))) - (clobber (reg:CC 33))] - "!TARGET_LONG_DISPLACEMENT" +(define_insn_and_split "*extendqi<mode>2_short_displ" + [(set (match_operand:GPR 0 "register_operand" "=d") + (sign_extend:GPR (match_operand:QI 1 "s_operand" "Q"))) + (clobber (reg:CC CC_REGNUM))] + "!TARGET_EXTIMM && !TARGET_LONG_DISPLACEMENT" "#" "&& reload_completed" [(parallel - [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_SETHIGH)) - (clobber (reg:CC 33))]) + [(set (match_dup 0) (unspec:GPR [(match_dup 1) (const_int 8)] UNSPEC_ICM)) + (clobber (reg:CC CC_REGNUM))]) (parallel - [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24))) - (clobber (reg:CC 33))])] - "") - -; -; extendqihi2 instruction pattern(s). -; - + [(set (match_dup 0) (ashiftrt:GPR (match_dup 0) (match_dup 2))) + (clobber (reg:CC CC_REGNUM))])] +{ + operands[1] = adjust_address (operands[1], BLKmode, 0); + set_mem_size (operands[1], GEN_INT (GET_MODE_SIZE (QImode))); + operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) + - GET_MODE_BITSIZE (QImode)); +}) ; ; zero_extendsidi2 instruction pattern(s). @@ -2641,7 +2883,6 @@ [(set (match_operand:DI 0 "register_operand" "") (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))] "" - " { if (!TARGET_64BIT) { @@ -2650,8 +2891,7 @@ emit_move_insn (gen_highpart (SImode, operands[0]), const0_rtx); DONE; } -} -") +}) (define_insn "*zero_extendsidi2" [(set (match_operand:DI 0 "register_operand" "=d,d") @@ -2663,64 +2903,40 @@ [(set_attr "op_type" "RRE,RXY")]) ; -; zero_extendhidi2 instruction pattern(s). +; LLGT-type instructions (zero-extend from 31 bit to 64 bit). ; -(define_expand "zero_extendhidi2" - [(set (match_operand:DI 0 "register_operand" "") - (zero_extend:DI (match_operand:HI 1 "register_operand" "")))] - "" - " -{ - if (!TARGET_64BIT) - { - rtx tmp = gen_reg_rtx (SImode); - emit_insn (gen_zero_extendhisi2 (tmp, operands[1])); - emit_insn (gen_zero_extendsidi2 (operands[0], tmp)); - DONE; - } - else - { - operands[1] = gen_lowpart (DImode, operands[1]); - emit_insn (gen_ashldi3 (operands[0], operands[1], GEN_INT (48))); - emit_insn (gen_lshrdi3 (operands[0], operands[0], GEN_INT (48))); - DONE; - } -} -") - -(define_insn "*zero_extendhidi2" +(define_insn "*llgt_sidi" [(set (match_operand:DI 0 "register_operand" "=d") - (zero_extend:DI (match_operand:HI 1 "memory_operand" "m")))] + (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "m") 0) + (const_int 2147483647)))] "TARGET_64BIT" - "llgh\t%0,%1" - [(set_attr "op_type" "RXY")]) + "llgt\t%0,%1" + [(set_attr "op_type" "RXE")]) -; -; LLGT-type instructions (zero-extend from 31 bit to 64 bit). -; +(define_insn_and_split "*llgt_sidi_split" + [(set (match_operand:DI 0 "register_operand" "=d") + (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "m") 0) + (const_int 2147483647))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_64BIT" + "#" + "&& reload_completed" + [(set (match_dup 0) + (and:DI (subreg:DI (match_dup 1) 0) + (const_int 2147483647)))] + "") (define_insn "*llgt_sisi" [(set (match_operand:SI 0 "register_operand" "=d,d") (and:SI (match_operand:SI 1 "nonimmediate_operand" "d,m") (const_int 2147483647)))] - "TARGET_64BIT" + "TARGET_ZARCH" "@ llgtr\t%0,%1 llgt\t%0,%1" [(set_attr "op_type" "RRE,RXE")]) -(define_split - [(set (match_operand:SI 0 "register_operand" "") - (and:SI (match_operand:SI 1 "nonimmediate_operand" "") - (const_int 2147483647))) - (clobber (reg:CC 33))] - "TARGET_64BIT && reload_completed" - [(set (match_dup 0) - (and:SI (match_dup 1) - (const_int 2147483647)))] - "") - (define_insn "*llgt_didi" [(set (match_operand:DI 0 "register_operand" "=d,d") (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o") @@ -2732,130 +2948,87 @@ [(set_attr "op_type" "RRE,RXE")]) (define_split - [(set (match_operand:DI 0 "register_operand" "") - (and:DI (match_operand:DI 1 "nonimmediate_operand" "") - (const_int 2147483647))) - (clobber (reg:CC 33))] - "TARGET_64BIT && reload_completed" + [(set (match_operand:GPR 0 "register_operand" "") + (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "") + (const_int 2147483647))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_ZARCH && reload_completed" [(set (match_dup 0) - (and:DI (match_dup 1) - (const_int 2147483647)))] - "") - -(define_insn "*llgt_sidi" - [(set (match_operand:DI 0 "register_operand" "=d") - (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "m") 0) - (const_int 2147483647)))] - "TARGET_64BIT" - "llgt\t%0,%1" - [(set_attr "op_type" "RXE")]) - -(define_insn_and_split "*llgt_sidi_split" - [(set (match_operand:DI 0 "register_operand" "=d") - (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "m") 0) - (const_int 2147483647))) - (clobber (reg:CC 33))] - "TARGET_64BIT" - "#" - "&& reload_completed" - [(set (match_dup 0) - (and:DI (subreg:DI (match_dup 1) 0) - (const_int 2147483647)))] + (and:GPR (match_dup 1) + (const_int 2147483647)))] "") ; -; zero_extendqidi2 instruction pattern(s) +; zero_extend(hi|qi)(si|di)2 instruction pattern(s). ; -(define_expand "zero_extendqidi2" +(define_expand "zero_extend<mode>di2" [(set (match_operand:DI 0 "register_operand" "") - (zero_extend:DI (match_operand:QI 1 "register_operand" "")))] + (zero_extend:DI (match_operand:HQI 1 "nonimmediate_operand" "")))] "" - " { if (!TARGET_64BIT) { rtx tmp = gen_reg_rtx (SImode); - emit_insn (gen_zero_extendqisi2 (tmp, operands[1])); + emit_insn (gen_zero_extend<mode>si2 (tmp, operands[1])); emit_insn (gen_zero_extendsidi2 (operands[0], tmp)); DONE; } - else + else if (!TARGET_EXTIMM) { + rtx bitcount = GEN_INT (GET_MODE_BITSIZE(DImode) - + GET_MODE_BITSIZE(<MODE>mode)); operands[1] = gen_lowpart (DImode, operands[1]); - emit_insn (gen_ashldi3 (operands[0], operands[1], GEN_INT (56))); - emit_insn (gen_lshrdi3 (operands[0], operands[0], GEN_INT (56))); + emit_insn (gen_ashldi3 (operands[0], operands[1], bitcount)); + emit_insn (gen_lshrdi3 (operands[0], operands[0], bitcount)); DONE; } -} -") - -(define_insn "*zero_extendqidi2" - [(set (match_operand:DI 0 "register_operand" "=d") - (zero_extend:DI (match_operand:QI 1 "memory_operand" "m")))] - "TARGET_64BIT" - "llgc\t%0,%1" - [(set_attr "op_type" "RXY")]) - -; -; zero_extendhisi2 instruction pattern(s). -; +}) -(define_expand "zero_extendhisi2" +(define_expand "zero_extend<mode>si2" [(set (match_operand:SI 0 "register_operand" "") - (zero_extend:SI (match_operand:HI 1 "register_operand" "")))] + (zero_extend:SI (match_operand:HQI 1 "nonimmediate_operand" "")))] "" - " { - operands[1] = gen_lowpart (SImode, operands[1]); - emit_insn (gen_andsi3 (operands[0], operands[1], GEN_INT (0xffff))); - DONE; -} -") + if (!TARGET_EXTIMM) + { + operands[1] = gen_lowpart (SImode, operands[1]); + emit_insn (gen_andsi3 (operands[0], operands[1], + GEN_INT ((1 << GET_MODE_BITSIZE(<MODE>mode)) - 1))); + DONE; + } +}) -(define_insn "*zero_extendhisi2_64" - [(set (match_operand:SI 0 "register_operand" "=d") - (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))] - "TARGET_64BIT" - "llgh\t%0,%1" +; llhr, llcr, llghr, llgcr, llh, llc, llgh, llgc +(define_insn "*zero_extend<HQI:mode><GPR:mode>2_extimm" + [(set (match_operand:GPR 0 "register_operand" "=d,d") + (zero_extend:GPR (match_operand:HQI 1 "nonimmediate_operand" "d,m")))] + "TARGET_EXTIMM" + "@ + ll<g><hc>r\t%0,%1 + ll<g><hc>\t%0,%1" + [(set_attr "op_type" "RRE,RXY")]) + +; llgh, llgc +(define_insn "*zero_extend<HQI:mode><GPR:mode>2" + [(set (match_operand:GPR 0 "register_operand" "=d") + (zero_extend:GPR (match_operand:HQI 1 "memory_operand" "m")))] + "TARGET_ZARCH && !TARGET_EXTIMM" + "llg<hc>\t%0,%1" [(set_attr "op_type" "RXY")]) (define_insn_and_split "*zero_extendhisi2_31" [(set (match_operand:SI 0 "register_operand" "=&d") (zero_extend:SI (match_operand:HI 1 "s_operand" "QS"))) - (clobber (reg:CC 33))] - "!TARGET_64BIT" + (clobber (reg:CC CC_REGNUM))] + "!TARGET_ZARCH" "#" "&& reload_completed" [(set (match_dup 0) (const_int 0)) (parallel [(set (strict_low_part (match_dup 2)) (match_dup 1)) - (clobber (reg:CC 33))])] - "operands[2] = gen_lowpart (HImode, operands[0]);" - [(set_attr "atype" "agen")]) - -; -; zero_extendqisi2 instruction pattern(s). -; - -(define_expand "zero_extendqisi2" - [(set (match_operand:SI 0 "register_operand" "") - (zero_extend:SI (match_operand:QI 1 "register_operand" "")))] - "" - " -{ - operands[1] = gen_lowpart (SImode, operands[1]); - emit_insn (gen_andsi3 (operands[0], operands[1], GEN_INT (0xff))); - DONE; -} -") - -(define_insn "*zero_extendqisi2_64" - [(set (match_operand:SI 0 "register_operand" "=d") - (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))] - "TARGET_ZARCH" - "llgc\t%0,%1" - [(set_attr "op_type" "RXY")]) + (clobber (reg:CC CC_REGNUM))])] + "operands[2] = gen_lowpart (HImode, operands[0]);") (define_insn_and_split "*zero_extendqisi2_31" [(set (match_operand:SI 0 "register_operand" "=&d") @@ -2865,8 +3038,7 @@ "&& reload_completed" [(set (match_dup 0) (const_int 0)) (set (strict_low_part (match_dup 2)) (match_dup 1))] - "operands[2] = gen_lowpart (QImode, operands[0]);" - [(set_attr "atype" "agen")]) + "operands[2] = gen_lowpart (QImode, operands[0]);") ; ; zero_extendqihi2 instruction pattern(s). @@ -2875,19 +3047,17 @@ (define_expand "zero_extendqihi2" [(set (match_operand:HI 0 "register_operand" "") (zero_extend:HI (match_operand:QI 1 "register_operand" "")))] - "TARGET_ZARCH" - " + "TARGET_ZARCH && !TARGET_EXTIMM" { operands[1] = gen_lowpart (HImode, operands[1]); emit_insn (gen_andhi3 (operands[0], operands[1], GEN_INT (0xff))); DONE; -} -") +}) (define_insn "*zero_extendqihi2_64" [(set (match_operand:HI 0 "register_operand" "=d") (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))] - "TARGET_ZARCH" + "TARGET_ZARCH && !TARGET_EXTIMM" "llgc\t%0,%1" [(set_attr "op_type" "RXY")]) @@ -2899,89 +3069,80 @@ "&& reload_completed" [(set (match_dup 0) (const_int 0)) (set (strict_low_part (match_dup 2)) (match_dup 1))] - "operands[2] = gen_lowpart (QImode, operands[0]);" - [(set_attr "atype" "agen")]) + "operands[2] = gen_lowpart (QImode, operands[0]);") ; -; fixuns_truncdfdi2 and fix_truncdfsi2 instruction pattern(s). +; fixuns_trunc(sf|df)(si|di)2 and fix_trunc(sf|df)(si|di)2 instruction pattern(s). ; -(define_expand "fixuns_truncdfdi2" - [(set (match_operand:DI 0 "register_operand" "") - (unsigned_fix:DI (match_operand:DF 1 "register_operand" "")))] - "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" +(define_expand "fixuns_trunc<FPR:mode><GPR:mode>2" + [(set (match_operand:GPR 0 "register_operand" "") + (unsigned_fix:GPR (match_operand:FPR 1 "register_operand" "")))] + "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" { rtx label1 = gen_label_rtx (); rtx label2 = gen_label_rtx (); - rtx temp = gen_reg_rtx (DFmode); - operands[1] = force_reg (DFmode, operands[1]); - - emit_insn (gen_cmpdf (operands[1], - CONST_DOUBLE_FROM_REAL_VALUE ( - REAL_VALUE_ATOF ("9223372036854775808.0", DFmode), DFmode))); + rtx temp = gen_reg_rtx (<FPR:MODE>mode); + REAL_VALUE_TYPE cmp, sub; + + operands[1] = force_reg (<FPR:MODE>mode, operands[1]); + real_2expN (&cmp, GET_MODE_BITSIZE(<GPR:MODE>mode) - 1); + real_2expN (&sub, GET_MODE_BITSIZE(<GPR:MODE>mode)); + + emit_insn (gen_cmp<FPR:mode> (operands[1], + CONST_DOUBLE_FROM_REAL_VALUE (cmp, <FPR:MODE>mode))); emit_jump_insn (gen_blt (label1)); - emit_insn (gen_subdf3 (temp, operands[1], - CONST_DOUBLE_FROM_REAL_VALUE ( - REAL_VALUE_ATOF ("18446744073709551616.0", DFmode), DFmode))); - emit_insn (gen_fix_truncdfdi2_ieee (operands[0], temp, GEN_INT(7))); + emit_insn (gen_sub<FPR:mode>3 (temp, operands[1], + CONST_DOUBLE_FROM_REAL_VALUE (sub, <FPR:MODE>mode))); + emit_insn (gen_fix_trunc<FPR:mode><GPR:mode>2_ieee (operands[0], temp, + GEN_INT(7))); emit_jump (label2); emit_label (label1); - emit_insn (gen_fix_truncdfdi2_ieee (operands[0], operands[1], GEN_INT(5))); + emit_insn (gen_fix_trunc<FPR:mode><GPR:mode>2_ieee (operands[0], + operands[1], GEN_INT(5))); emit_label (label2); DONE; }) -(define_expand "fix_truncdfdi2" +(define_expand "fix_trunc<mode>di2" [(set (match_operand:DI 0 "register_operand" "") - (fix:DI (match_operand:DF 1 "nonimmediate_operand" "")))] + (fix:DI (match_operand:DSF 1 "nonimmediate_operand" "")))] "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" { - operands[1] = force_reg (DFmode, operands[1]); - emit_insn (gen_fix_truncdfdi2_ieee (operands[0], operands[1], GEN_INT(5))); + operands[1] = force_reg (<MODE>mode, operands[1]); + emit_insn (gen_fix_trunc<mode>di2_ieee (operands[0], operands[1], + GEN_INT(5))); DONE; }) -(define_insn "fix_truncdfdi2_ieee" - [(set (match_operand:DI 0 "register_operand" "=d") - (fix:DI (match_operand:DF 1 "register_operand" "f"))) - (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] UNSPEC_ROUND) - (clobber (reg:CC 33))] - "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "cgdbr\t%0,%h2,%1" +; cgxbr, cgdbr, cgebr, cfxbr, cfdbr, cfebr +(define_insn "fix_trunc<FPR:mode><GPR:mode>2_ieee" + [(set (match_operand:GPR 0 "register_operand" "=d") + (fix:GPR (match_operand:FPR 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" + "c<GPR:gf><FPR:xde>br\t%0,%h2,%1" [(set_attr "op_type" "RRE") (set_attr "type" "ftoi")]) ; -; fixuns_truncdfsi2 and fix_truncdfsi2 instruction pattern(s). +; fix_trunctf(si|di)2 instruction pattern(s). ; -(define_expand "fixuns_truncdfsi2" - [(set (match_operand:SI 0 "register_operand" "") - (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))] +(define_expand "fix_trunctf<mode>2" + [(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 && TARGET_IEEE_FLOAT" -{ - rtx label1 = gen_label_rtx (); - rtx label2 = gen_label_rtx (); - rtx temp = gen_reg_rtx (DFmode); - - operands[1] = force_reg (DFmode,operands[1]); - emit_insn (gen_cmpdf (operands[1], - CONST_DOUBLE_FROM_REAL_VALUE ( - REAL_VALUE_ATOF ("2147483648.0", DFmode), DFmode))); - emit_jump_insn (gen_blt (label1)); - emit_insn (gen_subdf3 (temp, operands[1], - CONST_DOUBLE_FROM_REAL_VALUE ( - REAL_VALUE_ATOF ("4294967296.0", DFmode), DFmode))); - emit_insn (gen_fix_truncdfsi2_ieee (operands[0], temp, GEN_INT (7))); - emit_jump (label2); + "") - emit_label (label1); - emit_insn (gen_fix_truncdfsi2_ieee (operands[0], operands[1], GEN_INT (5))); - emit_label (label2); - DONE; -}) +; +; fix_truncdfsi2 instruction pattern(s). +; (define_expand "fix_truncdfsi2" [(set (match_operand:SI 0 "register_operand" "") @@ -3009,23 +3170,13 @@ DONE; }) -(define_insn "fix_truncdfsi2_ieee" - [(set (match_operand:SI 0 "register_operand" "=d") - (fix:SI (match_operand:DF 1 "register_operand" "f"))) - (unspec:SI [(match_operand:SI 2 "immediate_operand" "K")] UNSPEC_ROUND) - (clobber (reg:CC 33))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "cfdbr\t%0,%h2,%1" - [(set_attr "op_type" "RRE") - (set_attr "type" "other" )]) - (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")) - (clobber (reg:CC 33))] + (clobber (reg:CC CC_REGNUM))] "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" { output_asm_insn ("sd\t%1,%2", operands); @@ -3034,92 +3185,12 @@ output_asm_insn ("xi\t%N4,128", operands); return "l\t%0,%N4"; } - [(set_attr "op_type" "NN") - (set_attr "type" "ftoi") - (set_attr "atype" "agen") - (set_attr "length" "20")]) - -; -; fixuns_truncsfdi2 and fix_truncsfdi2 instruction pattern(s). -; - -(define_expand "fixuns_truncsfdi2" - [(set (match_operand:DI 0 "register_operand" "") - (unsigned_fix:DI (match_operand:SF 1 "register_operand" "")))] - "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" -{ - rtx label1 = gen_label_rtx (); - rtx label2 = gen_label_rtx (); - rtx temp = gen_reg_rtx (SFmode); - - operands[1] = force_reg (SFmode, operands[1]); - emit_insn (gen_cmpsf (operands[1], - CONST_DOUBLE_FROM_REAL_VALUE ( - REAL_VALUE_ATOF ("9223372036854775808.0", SFmode), SFmode))); - emit_jump_insn (gen_blt (label1)); - - emit_insn (gen_subsf3 (temp, operands[1], - CONST_DOUBLE_FROM_REAL_VALUE ( - REAL_VALUE_ATOF ("18446744073709551616.0", SFmode), SFmode))); - emit_insn (gen_fix_truncsfdi2_ieee (operands[0], temp, GEN_INT(7))); - emit_jump (label2); - - emit_label (label1); - emit_insn (gen_fix_truncsfdi2_ieee (operands[0], operands[1], GEN_INT(5))); - emit_label (label2); - DONE; -}) - -(define_expand "fix_truncsfdi2" - [(set (match_operand:DI 0 "register_operand" "") - (fix:DI (match_operand:SF 1 "nonimmediate_operand" "")))] - "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" -{ - operands[1] = force_reg (SFmode, operands[1]); - emit_insn (gen_fix_truncsfdi2_ieee (operands[0], operands[1], GEN_INT(5))); - DONE; -}) - -(define_insn "fix_truncsfdi2_ieee" - [(set (match_operand:DI 0 "register_operand" "=d") - (fix:DI (match_operand:SF 1 "register_operand" "f"))) - (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] UNSPEC_ROUND) - (clobber (reg:CC 33))] - "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "cgebr\t%0,%h2,%1" - [(set_attr "op_type" "RRE") - (set_attr "type" "ftoi")]) + [(set_attr "length" "20")]) ; -; fixuns_truncsfsi2 and fix_truncsfsi2 instruction pattern(s). +; fix_truncsfsi2 instruction pattern(s). ; -(define_expand "fixuns_truncsfsi2" - [(set (match_operand:SI 0 "register_operand" "") - (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" -{ - rtx label1 = gen_label_rtx (); - rtx label2 = gen_label_rtx (); - rtx temp = gen_reg_rtx (SFmode); - - operands[1] = force_reg (SFmode, operands[1]); - emit_insn (gen_cmpsf (operands[1], - CONST_DOUBLE_FROM_REAL_VALUE ( - REAL_VALUE_ATOF ("2147483648.0", SFmode), SFmode))); - emit_jump_insn (gen_blt (label1)); - emit_insn (gen_subsf3 (temp, operands[1], - CONST_DOUBLE_FROM_REAL_VALUE ( - REAL_VALUE_ATOF ("4294967296.0", SFmode), SFmode))); - emit_insn (gen_fix_truncsfsi2_ieee (operands[0], temp, GEN_INT (7))); - emit_jump (label2); - - emit_label (label1); - emit_insn (gen_fix_truncsfsi2_ieee (operands[0], operands[1], GEN_INT (5))); - emit_label (label2); - DONE; -}) - (define_expand "fix_truncsfsi2" [(set (match_operand:SI 0 "register_operand" "") (fix:SI (match_operand:SF 1 "nonimmediate_operand" "")))] @@ -3141,51 +3212,42 @@ DONE; }) -(define_insn "fix_truncsfsi2_ieee" - [(set (match_operand:SI 0 "register_operand" "=d") - (fix:SI (match_operand:SF 1 "register_operand" "f"))) - (unspec:SI [(match_operand:SI 2 "immediate_operand" "K")] UNSPEC_ROUND) - (clobber (reg:CC 33))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "cfebr\t%0,%h2,%1" - [(set_attr "op_type" "RRE") - (set_attr "type" "ftoi")]) - ; -; floatdidf2 instruction pattern(s). +; float(si|di)(tf|df|sf)2 instruction pattern(s). ; -(define_insn "floatdidf2" - [(set (match_operand:DF 0 "register_operand" "=f") - (float:DF (match_operand:DI 1 "register_operand" "d"))) - (clobber (reg:CC 33))] +; cxgbr, cdgbr, cegbr +(define_insn "floatdi<mode>2" + [(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" - "cdgbr\t%0,%1" + "c<xde>gbr\t%0,%1" [(set_attr "op_type" "RRE") (set_attr "type" "itof" )]) -; -; floatdisf2 instruction pattern(s). -; - -(define_insn "floatdisf2" - [(set (match_operand:SF 0 "register_operand" "=f") - (float:SF (match_operand:DI 1 "register_operand" "d"))) - (clobber (reg:CC 33))] - "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "cegbr\t%0,%1" +; cxfbr, cdfbr, cefbr +(define_insn "floatsi<mode>2_ieee" + [(set (match_operand:FPR 0 "register_operand" "=f") + (float:FPR (match_operand:SI 1 "register_operand" "d")))] + "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" + "c<xde>fbr\t%0,%1" [(set_attr "op_type" "RRE") - (set_attr "type" "itof" )]) + (set_attr "type" "itof" )]) + ; -; floatsidf2 instruction pattern(s). +; floatsi(tf|df)2 instruction pattern(s). ; +(define_expand "floatsitf2" + [(set (match_operand:TF 0 "register_operand" "") + (float:TF (match_operand:SI 1 "register_operand" "")))] + "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" + "") + (define_expand "floatsidf2" - [(parallel - [(set (match_operand:DF 0 "register_operand" "") - (float:DF (match_operand:SI 1 "register_operand" ""))) - (clobber (reg:CC 33))])] + [(set (match_operand:DF 0 "register_operand" "") + (float:DF (match_operand:SI 1 "register_operand" "")))] "TARGET_HARD_FLOAT" { if (TARGET_IBM_FLOAT) @@ -3200,21 +3262,12 @@ } }) -(define_insn "floatsidf2_ieee" - [(set (match_operand:DF 0 "register_operand" "=f") - (float:DF (match_operand:SI 1 "register_operand" "d"))) - (clobber (reg:CC 33))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "cdfbr\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 33))] + (clobber (reg:CC CC_REGNUM))] "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" { output_asm_insn ("st\t%1,%N3", operands); @@ -3223,20 +3276,15 @@ output_asm_insn ("ld\t%0,%3", operands); return "sd\t%0,%2"; } - [(set_attr "op_type" "NN") - (set_attr "type" "other" ) - (set_attr "atype" "agen") - (set_attr "length" "20")]) + [(set_attr "length" "20")]) ; ; floatsisf2 instruction pattern(s). ; (define_expand "floatsisf2" - [(parallel - [(set (match_operand:SF 0 "register_operand" "") - (float:SF (match_operand:SI 1 "register_operand" ""))) - (clobber (reg:CC 33))])] + [(set (match_operand:SF 0 "register_operand" "") + (float:SF (match_operand:SI 1 "register_operand" "")))] "TARGET_HARD_FLOAT" { if (TARGET_IBM_FLOAT) @@ -3249,41 +3297,93 @@ } }) -(define_insn "floatsisf2_ieee" - [(set (match_operand:SF 0 "register_operand" "=f") - (float:SF (match_operand:SI 1 "register_operand" "d"))) - (clobber (reg:CC 33))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "cefbr\t%0,%1" - [(set_attr "op_type" "RRE") - (set_attr "type" "itof" )]) - ; ; truncdfsf2 instruction pattern(s). ; (define_expand "truncdfsf2" [(set (match_operand:SF 0 "register_operand" "") - (float_truncate:SF (match_operand:DF 1 "general_operand" "")))] + (float_truncate:SF (match_operand:DF 1 "register_operand" "")))] "TARGET_HARD_FLOAT" "") (define_insn "truncdfsf2_ieee" [(set (match_operand:SF 0 "register_operand" "=f") - (float_truncate:SF (match_operand:DF 1 "general_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")]) + [(set_attr "op_type" "RRE") + (set_attr "type" "ftruncdf")]) (define_insn "truncdfsf2_ibm" [(set (match_operand:SF 0 "register_operand" "=f,f") - (float_truncate:SF (match_operand:DF 1 "general_operand" "f,R")))] + (float_truncate:SF (match_operand:DF 1 "nonimmediate_operand" "f,R")))] "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" "@ - lrer\t%0,%1 + ler\t%0,%1 le\t%0,%1" [(set_attr "op_type" "RR,RX") - (set_attr "type" "floads,floads")]) + (set_attr "type" "floadsf")]) + +; +; trunctfdf2 instruction pattern(s). +; + +(define_expand "trunctfdf2" + [(parallel + [(set (match_operand:DF 0 "register_operand" "") + (float_truncate:DF (match_operand:TF 1 "register_operand" ""))) + (clobber (match_scratch:TF 2 "=f"))])] + "TARGET_HARD_FLOAT" + "") + +(define_insn "*trunctfdf2_ieee" + [(set (match_operand:DF 0 "register_operand" "=f") + (float_truncate:DF (match_operand:TF 1 "register_operand" "f"))) + (clobber (match_scratch:TF 2 "=f"))] + "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" + "ldxbr\t%2,%1\;ldr\t%0,%2" + [(set_attr "length" "6") + (set_attr "type" "ftrunctf")]) + +(define_insn "*trunctfdf2_ibm" + [(set (match_operand:DF 0 "register_operand" "=f") + (float_truncate:DF (match_operand:TF 1 "register_operand" "f"))) + (clobber (match_scratch:TF 2 "=f"))] + "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" + "ldxr\t%2,%1\;ldr\t%0,%2" + [(set_attr "length" "4") + (set_attr "type" "ftrunctf")]) + +; +; trunctfsf2 instruction pattern(s). +; + +(define_expand "trunctfsf2" + [(parallel + [(set (match_operand:SF 0 "register_operand" "=f") + (float_truncate:SF (match_operand:TF 1 "register_operand" "f"))) + (clobber (match_scratch:TF 2 "=f"))])] + "TARGET_HARD_FLOAT" + "") + +(define_insn "*trunctfsf2_ieee" + [(set (match_operand:SF 0 "register_operand" "=f") + (float_truncate:SF (match_operand:TF 1 "register_operand" "f"))) + (clobber (match_scratch:TF 2 "=f"))] + "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" + "lexbr\t%2,%1\;ler\t%0,%2" + [(set_attr "length" "6") + (set_attr "type" "ftrunctf")]) + +(define_insn "*trunctfsf2_ibm" + [(set (match_operand:SF 0 "register_operand" "=f") + (float_truncate:SF (match_operand:TF 1 "register_operand" "f"))) + (clobber (match_scratch:TF 2 "=f"))] + "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" + "lexr\t%2,%1\;ler\t%0,%2" + [(set_attr "length" "6") + (set_attr "type" "ftrunctf")]) ; ; extendsfdf2 instruction pattern(s). @@ -3309,20 +3409,78 @@ ldebr\t%0,%1 ldeb\t%0,%1" [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "floads,floads")]) + (set_attr "type" "fsimpsf, floadsf")]) (define_insn "extendsfdf2_ibm" [(set (match_operand:DF 0 "register_operand" "=f,f") (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,R"))) - (clobber (reg:CC 33))] + (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 "op_type" "NN,NN") - (set_attr "atype" "reg,agen") - (set_attr "length" "4,6") - (set_attr "type" "o2,o2")]) + [(set_attr "length" "4,6") + (set_attr "type" "floadsf")]) + +; +; extenddftf2 instruction pattern(s). +; + +(define_expand "extenddftf2" + [(set (match_operand:TF 0 "register_operand" "") + (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "")))] + "TARGET_HARD_FLOAT" + "") + +(define_insn "*extenddftf2_ieee" + [(set (match_operand:TF 0 "register_operand" "=f,f") + (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f,R")))] + "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" + "@ + lxdbr\t%0,%1 + lxdb\t%0,%1" + [(set_attr "op_type" "RRE,RXE") + (set_attr "type" "fsimptf, floadtf")]) + +(define_insn "*extenddftf2_ibm" + [(set (match_operand:TF 0 "register_operand" "=f,f") + (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f,R")))] + "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" + "@ + lxdr\t%0,%1 + lxd\t%0,%1" + [(set_attr "op_type" "RRE,RXE") + (set_attr "type" "fsimptf, floadtf")]) + +; +; extendsftf2 instruction pattern(s). +; + +(define_expand "extendsftf2" + [(set (match_operand:TF 0 "register_operand" "") + (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "")))] + "TARGET_HARD_FLOAT" + "") + +(define_insn "*extendsftf2_ieee" + [(set (match_operand:TF 0 "register_operand" "=f,f") + (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f,R")))] + "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" + "@ + lxebr\t%0,%1 + lxeb\t%0,%1" + [(set_attr "op_type" "RRE,RXE") + (set_attr "type" "fsimptf, floadtf")]) + +(define_insn "*extendsftf2_ibm" + [(set (match_operand:TF 0 "register_operand" "=f,f") + (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f,R")))] + "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" + "@ + lxer\t%0,%1 + lxe\t%0,%1" + [(set_attr "op_type" "RRE,RXE") + (set_attr "type" "fsimptf, floadtf")]) ;; @@ -3337,14 +3495,51 @@ ;; ; +; addti3 instruction pattern(s). +; + +(define_insn_and_split "addti3" + [(set (match_operand:TI 0 "register_operand" "=&d") + (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0") + (match_operand:TI 2 "general_operand" "do") ) ) + (clobber (reg:CC CC_REGNUM))] + "TARGET_64BIT" + "#" + "&& reload_completed" + [(parallel + [(set (reg:CCL1 CC_REGNUM) + (compare:CCL1 (plus:DI (match_dup 7) (match_dup 8)) + (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)))) + (clobber (reg:CC CC_REGNUM))])] + "operands[3] = operand_subword (operands[0], 0, 0, TImode); + operands[4] = operand_subword (operands[1], 0, 0, TImode); + operands[5] = operand_subword (operands[2], 0, 0, TImode); + operands[6] = operand_subword (operands[0], 1, 0, TImode); + operands[7] = operand_subword (operands[1], 1, 0, TImode); + operands[8] = operand_subword (operands[2], 1, 0, TImode);") + +; ; 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")) (match_operand:DI 1 "register_operand" "0,0"))) - (clobber (reg:CC 33))] + (clobber (reg:CC CC_REGNUM))] "TARGET_64BIT" "@ agfr\t%0,%2 @@ -3352,7 +3547,7 @@ [(set_attr "op_type" "RRE,RXY")]) (define_insn "*adddi3_zero_cc" - [(set (reg 33) + [(set (reg CC_REGNUM) (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m")) (match_operand:DI 1 "register_operand" "0,0")) (const_int 0))) @@ -3365,7 +3560,7 @@ [(set_attr "op_type" "RRE,RXY")]) (define_insn "*adddi3_zero_cconly" - [(set (reg 33) + [(set (reg CC_REGNUM) (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m")) (match_operand:DI 1 "register_operand" "0,0")) (const_int 0))) @@ -3380,172 +3575,60 @@ [(set (match_operand:DI 0 "register_operand" "=d,d") (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m")) (match_operand:DI 1 "register_operand" "0,0"))) - (clobber (reg:CC 33))] + (clobber (reg:CC CC_REGNUM))] "TARGET_64BIT" "@ algfr\t%0,%2 algf\t%0,%2" [(set_attr "op_type" "RRE,RXY")]) -(define_insn "*adddi3_imm_cc" - [(set (reg 33) - (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "0") - (match_operand:DI 2 "const_int_operand" "K")) - (const_int 0))) - (set (match_operand:DI 0 "register_operand" "=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\")" - "aghi\t%0,%h2" - [(set_attr "op_type" "RI")]) - -(define_insn "*adddi3_carry1_cc" - [(set (reg 33) - (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") - (match_operand:DI 2 "general_operand" "d,m")) - (match_dup 1))) - (set (match_operand:DI 0 "register_operand" "=d,d") - (plus:DI (match_dup 1) (match_dup 2)))] - "s390_match_ccmode (insn, CCL1mode) && TARGET_64BIT" - "@ - algr\t%0,%2 - alg\t%0,%2" - [(set_attr "op_type" "RRE,RXY")]) - -(define_insn "*adddi3_carry1_cconly" - [(set (reg 33) - (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 33) - (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") - (match_operand:DI 2 "general_operand" "d,m")) - (match_dup 2))) - (set (match_operand:DI 0 "register_operand" "=d,d") - (plus:DI (match_dup 1) (match_dup 2)))] - "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_cconly" - [(set (reg 33) - (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 33) - (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") - (match_operand:DI 2 "general_operand" "d,m")) - (const_int 0))) - (set (match_operand:DI 0 "register_operand" "=d,d") - (plus:DI (match_dup 1) (match_dup 2)))] - "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT" - "@ - algr\t%0,%2 - alg\t%0,%2" - [(set_attr "op_type" "RRE,RXY")]) - -(define_insn "*adddi3_cconly" - [(set (reg 33) - (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 33) - (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") - (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:DI 2 "general_operand" "d,K,m") ) ) - (clobber (reg:CC 33))] - "TARGET_64BIT" - "@ - agr\t%0,%2 - aghi\t%0,%h2 - ag\t%0,%2" - [(set_attr "op_type" "RRE,RI,RXY")]) - (define_insn_and_split "*adddi3_31z" [(set (match_operand:DI 0 "register_operand" "=&d") (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0") (match_operand:DI 2 "general_operand" "do") ) ) - (clobber (reg:CC 33))] + (clobber (reg:CC CC_REGNUM))] "!TARGET_64BIT && TARGET_CPU_ZARCH" "#" "&& reload_completed" [(parallel - [(set (reg:CCL1 33) + [(set (reg:CCL1 CC_REGNUM) (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8)) (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 33) (const_int 0)))) - (clobber (reg:CC 33))])] + (ltu:SI (reg:CCL1 CC_REGNUM) (const_int 0)))) + (clobber (reg:CC CC_REGNUM))])] "operands[3] = operand_subword (operands[0], 0, 0, DImode); operands[4] = operand_subword (operands[1], 0, 0, DImode); operands[5] = operand_subword (operands[2], 0, 0, DImode); operands[6] = operand_subword (operands[0], 1, 0, DImode); operands[7] = operand_subword (operands[1], 1, 0, DImode); - operands[8] = operand_subword (operands[2], 1, 0, DImode);" - [(set_attr "op_type" "NN")]) + operands[8] = operand_subword (operands[2], 1, 0, DImode);") (define_insn_and_split "*adddi3_31" [(set (match_operand:DI 0 "register_operand" "=&d") (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0") (match_operand:DI 2 "general_operand" "do") ) ) - (clobber (reg:CC 33))] + (clobber (reg:CC CC_REGNUM))] "!TARGET_CPU_ZARCH" "#" "&& reload_completed" [(parallel [(set (match_dup 3) (plus:SI (match_dup 4) (match_dup 5))) - (clobber (reg:CC 33))]) + (clobber (reg:CC CC_REGNUM))]) (parallel - [(set (reg:CCL1 33) + [(set (reg:CCL1 CC_REGNUM) (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8)) (match_dup 7))) (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))]) (set (pc) - (if_then_else (ltu (reg:CCL1 33) (const_int 0)) + (if_then_else (ltu (reg:CCL1 CC_REGNUM) (const_int 0)) (pc) (label_ref (match_dup 9)))) (parallel [(set (match_dup 3) (plus:SI (match_dup 3) (const_int 1))) - (clobber (reg:CC 33))]) + (clobber (reg:CC CC_REGNUM))]) (match_dup 9)] "operands[3] = operand_subword (operands[0], 0, 0, DImode); operands[4] = operand_subword (operands[1], 0, 0, DImode); @@ -3553,278 +3636,242 @@ operands[6] = operand_subword (operands[0], 1, 0, DImode); operands[7] = operand_subword (operands[1], 1, 0, DImode); operands[8] = operand_subword (operands[2], 1, 0, DImode); - operands[9] = gen_label_rtx ();" - [(set_attr "op_type" "NN")]) + 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" ""))) - (clobber (reg:CC 33))])] + [(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 33) - (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "0") - (match_operand:SI 2 "const_int_operand" "K")) - (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=d") - (plus:SI (match_dup 1) (match_dup 2)))] - "s390_match_ccmode (insn, CCAmode) - && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\")" - "ahi\t%0,%h2" - [(set_attr "op_type" "RI")]) - -(define_insn "*addsi3_carry1_cc" - [(set (reg 33) - (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T")) +; ar, ahi, alfi, slfi, a, ay, agr, aghi, algfi, slgfi, ag +(define_insn "*add<mode>3" + [(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))] + "" + "@ + a<g>r\t%0,%2 + a<g>hi\t%0,%h2 + al<g>fi\t%0,%2 + sl<g>fi\t%0,%n2 + a<g>\t%0,%2 + a<y>\t%0,%2" + [(set_attr "op_type" "RR<E>,RI,RIL,RIL,RX<Y>,RXY")]) + +; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg +(define_insn "*add<mode>3_carry1_cc" + [(set (reg CC_REGNUM) + (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") - (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 - al\t%0,%2 - aly\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) - -(define_insn "*addsi3_carry1_cconly" - [(set (reg 33) - (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T")) + al<g>r\t%0,%2 + al<g>fi\t%0,%2 + sl<g>fi\t%0,%n2 + al<g>\t%0,%2 + al<y>\t%0,%2" + [(set_attr "op_type" "RR<E>,RIL,RIL,RX<Y>,RXY")]) + +; alr, al, aly, algr, alg +(define_insn "*add<mode>3_carry1_cconly" + [(set (reg CC_REGNUM) + (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")]) + al<g>r\t%0,%2 + al<g>\t%0,%2 + al<y>\t%0,%2" + [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) -(define_insn "*addsi3_carry2_cc" - [(set (reg 33) - (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T")) +; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg +(define_insn "*add<mode>3_carry2_cc" + [(set (reg CC_REGNUM) + (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") - (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 - al\t%0,%2 - aly\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) - -(define_insn "*addsi3_carry2_cconly" - [(set (reg 33) - (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T")) + al<g>r\t%0,%2 + al<g>fi\t%0,%2 + sl<g>fi\t%0,%n2 + al<g>\t%0,%2 + al<y>\t%0,%2" + [(set_attr "op_type" "RR<E>,RIL,RIL,RX<Y>,RXY")]) + +; alr, al, aly, algr, alg +(define_insn "*add<mode>3_carry2_cconly" + [(set (reg CC_REGNUM) + (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")]) + al<g>r\t%0,%2 + al<g>\t%0,%2 + al<y>\t%0,%2" + [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) -(define_insn "*addsi3_cc" - [(set (reg 33) - (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T")) +; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg +(define_insn "*add<mode>3_cc" + [(set (reg CC_REGNUM) + (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))) - (set (match_operand:SI 0 "register_operand" "=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, CCLmode)" "@ - alr\t%0,%2 - al\t%0,%2 - aly\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) - -(define_insn "*addsi3_cconly" - [(set (reg 33) - (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T")) + al<g>r\t%0,%2 + al<g>fi\t%0,%2 + sl<g>fi\t%0,%n2 + al<g>\t%0,%2 + al<y>\t%0,%2" + [(set_attr "op_type" "RR<E>,RIL,RIL,RX<Y>,RXY")]) + +; alr, al, aly, algr, alg +(define_insn "*add<mode>3_cconly" + [(set (reg CC_REGNUM) + (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:SI 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_cconly2" - [(set (reg 33) - (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"))] + (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 (match_operand:SI 1 "register_operand" "0,0") - (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T")))) - (clobber (reg:CC 33))] - "" - "@ - ah\t%0,%2 - ahy\t%0,%2" - [(set_attr "op_type" "RX,RXY")]) - -(define_insn "addsi3" - [(set (match_operand:SI 0 "register_operand" "=d,d,d,d") - (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0") - (match_operand:SI 2 "general_operand" "d,K,R,T"))) - (clobber (reg:CC 33))] - "" - "@ - ar\t%0,%2 - ahi\t%0,%h2 - a\t%0,%2 - ay\t%0,%2" - [(set_attr "op_type" "RR,RI,RX,RXY")]) - -; -; adddf3 instruction pattern(s). -; - -(define_expand "adddf3" - [(parallel - [(set (match_operand:DF 0 "register_operand" "=f,f") - (plus:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0") - (match_operand:DF 2 "general_operand" "f,R"))) - (clobber (reg:CC 33))])] - "TARGET_HARD_FLOAT" - "") - -(define_insn "*adddf3" - [(set (match_operand:DF 0 "register_operand" "=f,f") - (plus:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0") - (match_operand:DF 2 "general_operand" "f,R"))) - (clobber (reg:CC 33))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "@ - adbr\t%0,%2 - adb\t%0,%2" - [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fsimpd,fsimpd")]) - -(define_insn "*adddf3_cc" - [(set (reg 33) - (compare (plus:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0") - (match_operand:DF 2 "general_operand" "f,R")) - (match_operand:DF 3 "const0_operand" ""))) - (set (match_operand:DF 0 "register_operand" "=f,f") - (plus:DF (match_dup 1) (match_dup 2)))] - "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "@ - adbr\t%0,%2 - adb\t%0,%2" - [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fsimpd,fsimpd")]) - -(define_insn "*adddf3_cconly" - [(set (reg 33) - (compare (plus:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0") - (match_operand:DF 2 "general_operand" "f,R")) - (match_operand:DF 3 "const0_operand" ""))) - (clobber (match_scratch:DF 0 "=f,f"))] - "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "@ - adbr\t%0,%2 - adb\t%0,%2" - [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fsimpd,fsimpd")]) - -(define_insn "*adddf3_ibm" - [(set (match_operand:DF 0 "register_operand" "=f,f") - (plus:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0") - (match_operand:DF 2 "general_operand" "f,R"))) - (clobber (reg:CC 33))] - "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" + al<g>r\t%0,%2 + al<g>\t%0,%2 + al<y>\t%0,%2" + [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) + +; alr, al, aly, algr, alg +(define_insn "*add<mode>3_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)" + "@ + al<g>r\t%0,%2 + al<g>\t%0,%2 + al<y>\t%0,%2" + [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) + +; ahi, afi, aghi, agfi +(define_insn "*add<mode>3_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>mode) - 1))" "@ - adr\t%0,%2 - ad\t%0,%2" - [(set_attr "op_type" "RR,RX") - (set_attr "type" "fsimpd,fsimpd")]) + a<g>hi\t%0,%h2 + a<g>fi\t%0,%2" + [(set_attr "op_type" "RI,RIL")]) ; -; addsf3 instruction pattern(s). +; add(df|sf)3 instruction pattern(s). ; -(define_expand "addsf3" +(define_expand "add<mode>3" [(parallel - [(set (match_operand:SF 0 "register_operand" "=f,f") - (plus:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0") - (match_operand:SF 2 "general_operand" "f,R"))) - (clobber (reg:CC 33))])] + [(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,<Rf>"))) + (clobber (reg:CC CC_REGNUM))])] "TARGET_HARD_FLOAT" "") -(define_insn "*addsf3" - [(set (match_operand:SF 0 "register_operand" "=f,f") - (plus:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0") - (match_operand:SF 2 "general_operand" "f,R"))) - (clobber (reg:CC 33))] +; axbr, adbr, aebr, axb, adb, aeb +(define_insn "*add<mode>3" + [(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,<Rf>"))) + (clobber (reg:CC CC_REGNUM))] "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" "@ - aebr\t%0,%2 - aeb\t%0,%2" + a<xde>br\t%0,%2 + a<xde>b\t%0,%2" [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fsimps,fsimps")]) - -(define_insn "*addsf3_cc" - [(set (reg 33) - (compare (plus:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0") - (match_operand:SF 2 "general_operand" "f,R")) - (match_operand:SF 3 "const0_operand" ""))) - (set (match_operand:SF 0 "register_operand" "=f,f") - (plus:SF (match_dup 1) (match_dup 2)))] + (set_attr "type" "fsimp<mode>")]) + +; axbr, adbr, aebr, axb, adb, aeb +(define_insn "*add<mode>3_cc" + [(set (reg CC_REGNUM) + (compare (plus:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0") + (match_operand:FPR 2 "general_operand" "f,<Rf>")) + (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" "@ - aebr\t%0,%2 - aeb\t%0,%2" + a<xde>br\t%0,%2 + a<xde>b\t%0,%2" [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fsimps,fsimps")]) - -(define_insn "*addsf3_cconly" - [(set (reg 33) - (compare (plus:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0") - (match_operand:SF 2 "general_operand" "f,R")) - (match_operand:SF 3 "const0_operand" ""))) - (clobber (match_scratch:SF 0 "=f,f"))] + (set_attr "type" "fsimp<mode>")]) + +; axbr, adbr, aebr, axb, adb, aeb +(define_insn "*add<mode>3_cconly" + [(set (reg CC_REGNUM) + (compare (plus:FPR (match_operand:FPR 1 "nonimmediate_operand" "%0,0") + (match_operand:FPR 2 "general_operand" "f,<Rf>")) + (match_operand:FPR 3 "const0_operand" ""))) + (clobber (match_scratch:FPR 0 "=f,f"))] "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" "@ - aebr\t%0,%2 - aeb\t%0,%2" + a<xde>br\t%0,%2 + a<xde>b\t%0,%2" [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fsimps,fsimps")]) - -(define_insn "*addsf3" - [(set (match_operand:SF 0 "register_operand" "=f,f") - (plus:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0") - (match_operand:SF 2 "general_operand" "f,R"))) - (clobber (reg:CC 33))] + (set_attr "type" "fsimp<mode>")]) + +; axr, adr, aer, ax, ad, ae +(define_insn "*add<mode>3_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,<Rf>"))) + (clobber (reg:CC CC_REGNUM))] "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" "@ - aer\t%0,%2 - ae\t%0,%2" - [(set_attr "op_type" "RR,RX") - (set_attr "type" "fsimps,fsimps")]) + a<xde>r\t%0,%2 + a<xde>\t%0,%2" + [(set_attr "op_type" "<RRe>,<RXe>") + (set_attr "type" "fsimp<mode>")]) ;; @@ -3832,14 +3879,51 @@ ;; ; +; subti3 instruction pattern(s). +; + +(define_insn_and_split "subti3" + [(set (match_operand:TI 0 "register_operand" "=&d") + (minus:TI (match_operand:TI 1 "register_operand" "0") + (match_operand:TI 2 "general_operand" "do") ) ) + (clobber (reg:CC CC_REGNUM))] + "TARGET_64BIT" + "#" + "&& reload_completed" + [(parallel + [(set (reg:CCL2 CC_REGNUM) + (compare:CCL2 (minus:DI (match_dup 7) (match_dup 8)) + (match_dup 7))) + (set (match_dup 6) (minus:DI (match_dup 7) (match_dup 8)))]) + (parallel + [(set (match_dup 3) (minus:DI (minus:DI (match_dup 4) (match_dup 5)) + (gtu:DI (reg:CCL2 CC_REGNUM) (const_int 0)))) + (clobber (reg:CC CC_REGNUM))])] + "operands[3] = operand_subword (operands[0], 0, 0, TImode); + operands[4] = operand_subword (operands[1], 0, 0, TImode); + operands[5] = operand_subword (operands[2], 0, 0, TImode); + operands[6] = operand_subword (operands[0], 1, 0, TImode); + operands[7] = operand_subword (operands[1], 1, 0, TImode); + operands[8] = operand_subword (operands[2], 1, 0, TImode);") + +; ; 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") (sign_extend:DI (match_operand:SI 2 "general_operand" "d,m")))) - (clobber (reg:CC 33))] + (clobber (reg:CC CC_REGNUM))] "TARGET_64BIT" "@ sgfr\t%0,%2 @@ -3847,7 +3931,7 @@ [(set_attr "op_type" "RRE,RXY")]) (define_insn "*subdi3_zero_cc" - [(set (reg 33) + [(set (reg CC_REGNUM) (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0") (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m"))) (const_int 0))) @@ -3860,7 +3944,7 @@ [(set_attr "op_type" "RRE,RXY")]) (define_insn "*subdi3_zero_cconly" - [(set (reg 33) + [(set (reg CC_REGNUM) (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0") (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m"))) (const_int 0))) @@ -3875,122 +3959,60 @@ [(set (match_operand:DI 0 "register_operand" "=d,d") (minus:DI (match_operand:DI 1 "register_operand" "0,0") (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m")))) - (clobber (reg:CC 33))] + (clobber (reg:CC CC_REGNUM))] "TARGET_64BIT" "@ slgfr\t%0,%2 slgf\t%0,%2" [(set_attr "op_type" "RRE,RXY")]) -(define_insn "*subdi3_borrow_cc" - [(set (reg 33) - (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 33) - (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 33) - (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_cconly" - [(set (reg 33) - (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_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 33))] - "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") (match_operand:DI 2 "general_operand" "do") ) ) - (clobber (reg:CC 33))] + (clobber (reg:CC CC_REGNUM))] "!TARGET_64BIT && TARGET_CPU_ZARCH" "#" "&& reload_completed" [(parallel - [(set (reg:CCL2 33) + [(set (reg:CCL2 CC_REGNUM) (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8)) (match_dup 7))) (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))]) (parallel [(set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5)) - (gtu:SI (reg:CCL2 33) (const_int 0)))) - (clobber (reg:CC 33))])] + (gtu:SI (reg:CCL2 CC_REGNUM) (const_int 0)))) + (clobber (reg:CC CC_REGNUM))])] "operands[3] = operand_subword (operands[0], 0, 0, DImode); operands[4] = operand_subword (operands[1], 0, 0, DImode); operands[5] = operand_subword (operands[2], 0, 0, DImode); operands[6] = operand_subword (operands[0], 1, 0, DImode); operands[7] = operand_subword (operands[1], 1, 0, DImode); - operands[8] = operand_subword (operands[2], 1, 0, DImode);" - [(set_attr "op_type" "NN")]) + operands[8] = operand_subword (operands[2], 1, 0, DImode);") (define_insn_and_split "*subdi3_31" [(set (match_operand:DI 0 "register_operand" "=&d") (minus:DI (match_operand:DI 1 "register_operand" "0") (match_operand:DI 2 "general_operand" "do") ) ) - (clobber (reg:CC 33))] + (clobber (reg:CC CC_REGNUM))] "!TARGET_CPU_ZARCH" "#" "&& reload_completed" [(parallel [(set (match_dup 3) (minus:SI (match_dup 4) (match_dup 5))) - (clobber (reg:CC 33))]) + (clobber (reg:CC CC_REGNUM))]) (parallel - [(set (reg:CCL2 33) + [(set (reg:CCL2 CC_REGNUM) (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8)) (match_dup 7))) (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))]) (set (pc) - (if_then_else (gtu (reg:CCL2 33) (const_int 0)) + (if_then_else (gtu (reg:CCL2 CC_REGNUM) (const_int 0)) (pc) (label_ref (match_dup 9)))) (parallel [(set (match_dup 3) (plus:SI (match_dup 3) (const_int -1))) - (clobber (reg:CC 33))]) + (clobber (reg:CC CC_REGNUM))]) (match_dup 9)] "operands[3] = operand_subword (operands[0], 0, 0, DImode); operands[4] = operand_subword (operands[1], 0, 0, DImode); @@ -3998,227 +4020,201 @@ operands[6] = operand_subword (operands[0], 1, 0, DImode); operands[7] = operand_subword (operands[1], 1, 0, DImode); operands[8] = operand_subword (operands[2], 1, 0, DImode); - operands[9] = gen_label_rtx ();" - [(set_attr "op_type" "NN")]) - -(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 33))])] - "" - "") + operands[9] = gen_label_rtx ();") ; ; subsi3 instruction pattern(s). ; -(define_insn "*subsi3_borrow_cc" - [(set (reg 33) - (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0,0") - (match_operand:SI 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)))] - "s390_match_ccmode (insn, CCL2mode)" - "@ - slr\t%0,%2 - sl\t%0,%2 - sly\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) - -(define_insn "*subsi3_borrow_cconly" - [(set (reg 33) - (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T")) - (match_dup 1))) - (clobber (match_scratch:SI 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")]) - -(define_insn "*subsi3_cc" - [(set (reg 33) - (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0,0") - (match_operand:SI 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)))] - "s390_match_ccmode (insn, CCLmode)" - "@ - slr\t%0,%2 - sl\t%0,%2 - sly\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) - -(define_insn "*subsi3_cconly" - [(set (reg 33) - (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T")) - (const_int 0))) - (clobber (match_scratch:SI 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")]) +(define_expand "subsi3" + [(parallel + [(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 33))] + (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 33))] - "" - "@ - sr\t%0,%2 - s\t%0,%2 - sy\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) - - ; -; subdf3 instruction pattern(s). +; sub(di|si)3 instruction pattern(s). ; -(define_expand "subdf3" - [(parallel - [(set (match_operand:DF 0 "register_operand" "=f,f") - (minus:DF (match_operand:DF 1 "register_operand" "0,0") - (match_operand:DF 2 "general_operand" "f,R"))) - (clobber (reg:CC 33))])] - "TARGET_HARD_FLOAT" - "") +; sr, s, sy, sgr, sg +(define_insn "*sub<mode>3" + [(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))] + "" + "@ + s<g>r\t%0,%2 + s<g>\t%0,%2 + s<y>\t%0,%2" + [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) -(define_insn "*subdf3" - [(set (match_operand:DF 0 "register_operand" "=f,f") - (minus:DF (match_operand:DF 1 "register_operand" "0,0") - (match_operand:DF 2 "general_operand" "f,R"))) - (clobber (reg:CC 33))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" +; slr, sl, sly, slgr, slg +(define_insn "*sub<mode>3_borrow_cc" + [(set (reg CC_REGNUM) + (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:GPR 0 "register_operand" "=d,d,d") + (minus:GPR (match_dup 1) (match_dup 2)))] + "s390_match_ccmode (insn, CCL2mode)" "@ - sdbr\t%0,%2 - sdb\t%0,%2" - [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fsimpd,fsimpd")]) - -(define_insn "*subdf3_cc" - [(set (reg 33) - (compare (minus:DF (match_operand:DF 1 "nonimmediate_operand" "0,0") - (match_operand:DF 2 "general_operand" "f,R")) - (match_operand:DF 3 "const0_operand" ""))) - (set (match_operand:DF 0 "register_operand" "=f,f") - (minus:DF (match_dup 1) (match_dup 2)))] - "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" + sl<g>r\t%0,%2 + sl<g>\t%0,%2 + sl<y>\t%0,%2" + [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) + +; slr, sl, sly, slgr, slg +(define_insn "*sub<mode>3_borrow_cconly" + [(set (reg CC_REGNUM) + (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:GPR 0 "=d,d,d"))] + "s390_match_ccmode (insn, CCL2mode)" "@ - sdbr\t%0,%2 - sdb\t%0,%2" - [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fsimpd,fsimpd")]) - -(define_insn "*subdf3_cconly" - [(set (reg 33) - (compare (minus:DF (match_operand:DF 1 "nonimmediate_operand" "0,0") - (match_operand:DF 2 "general_operand" "f,R")) - (match_operand:DF 3 "const0_operand" ""))) - (clobber (match_scratch:DF 0 "=f,f"))] - "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" + sl<g>r\t%0,%2 + sl<g>\t%0,%2 + sl<y>\t%0,%2" + [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) + +; slr, sl, sly, slgr, slg +(define_insn "*sub<mode>3_cc" + [(set (reg CC_REGNUM) + (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:GPR 0 "register_operand" "=d,d,d") + (minus:GPR (match_dup 1) (match_dup 2)))] + "s390_match_ccmode (insn, CCLmode)" "@ - sdbr\t%0,%2 - sdb\t%0,%2" - [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fsimpd,fsimpd")]) + sl<g>r\t%0,%2 + sl<g>\t%0,%2 + sl<y>\t%0,%2" + [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) + +; slr, sl, sly, slgr, slg +(define_insn "*sub<mode>3_cc2" + [(set (reg CC_REGNUM) + (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)" + "@ + sl<g>r\t%0,%2 + sl<g>\t%0,%2 + sl<y>\t%0,%2" + [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) + +; slr, sl, sly, slgr, slg +(define_insn "*sub<mode>3_cconly" + [(set (reg CC_REGNUM) + (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:GPR 0 "=d,d,d"))] + "s390_match_ccmode (insn, CCLmode)" + "@ + sl<g>r\t%0,%2 + sl<g>\t%0,%2 + sl<y>\t%0,%2" + [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) -(define_insn "*subdf3_ibm" - [(set (match_operand:DF 0 "register_operand" "=f,f") - (minus:DF (match_operand:DF 1 "register_operand" "0,0") - (match_operand:DF 2 "general_operand" "f,R"))) - (clobber (reg:CC 33))] - "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" +; slr, sl, sly, slgr, slg +(define_insn "*sub<mode>3_cconly2" + [(set (reg CC_REGNUM) + (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)" "@ - sdr\t%0,%2 - sd\t%0,%2" - [(set_attr "op_type" "RR,RX") - (set_attr "type" "fsimpd,fsimpd")]) + sl<g>r\t%0,%2 + sl<g>\t%0,%2 + sl<y>\t%0,%2" + [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) ; -; subsf3 instruction pattern(s). +; sub(df|sf)3 instruction pattern(s). ; -(define_expand "subsf3" +(define_expand "sub<mode>3" [(parallel - [(set (match_operand:SF 0 "register_operand" "=f,f") - (minus:SF (match_operand:SF 1 "register_operand" "0,0") - (match_operand:SF 2 "general_operand" "f,R"))) - (clobber (reg:CC 33))])] + [(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 "*subsf3" - [(set (match_operand:SF 0 "register_operand" "=f,f") - (minus:SF (match_operand:SF 1 "register_operand" "0,0") - (match_operand:SF 2 "general_operand" "f,R"))) - (clobber (reg:CC 33))] +; sxbr, sdbr, sebr, sxb, sdb, seb +(define_insn "*sub<mode>3" + [(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,<Rf>"))) + (clobber (reg:CC CC_REGNUM))] "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" "@ - sebr\t%0,%2 - seb\t%0,%2" + s<xde>br\t%0,%2 + s<xde>b\t%0,%2" [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fsimps,fsimps")]) - -(define_insn "*subsf3_cc" - [(set (reg 33) - (compare (minus:SF (match_operand:SF 1 "nonimmediate_operand" "0,0") - (match_operand:SF 2 "general_operand" "f,R")) - (match_operand:SF 3 "const0_operand" ""))) - (set (match_operand:SF 0 "register_operand" "=f,f") - (minus:SF (match_dup 1) (match_dup 2)))] + (set_attr "type" "fsimp<mode>")]) + +; sxbr, sdbr, sebr, sxb, sdb, seb +(define_insn "*sub<mode>3_cc" + [(set (reg CC_REGNUM) + (compare (minus:FPR (match_operand:FPR 1 "nonimmediate_operand" "0,0") + (match_operand:FPR 2 "general_operand" "f,<Rf>")) + (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" "@ - sebr\t%0,%2 - seb\t%0,%2" + s<xde>br\t%0,%2 + s<xde>b\t%0,%2" [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fsimps,fsimps")]) - -(define_insn "*subsf3_cconly" - [(set (reg 33) - (compare (minus:SF (match_operand:SF 1 "nonimmediate_operand" "0,0") - (match_operand:SF 2 "general_operand" "f,R")) - (match_operand:SF 3 "const0_operand" ""))) - (clobber (match_scratch:SF 0 "=f,f"))] + (set_attr "type" "fsimp<mode>")]) + +; sxbr, sdbr, sebr, sxb, sdb, seb +(define_insn "*sub<mode>3_cconly" + [(set (reg CC_REGNUM) + (compare (minus:FPR (match_operand:FPR 1 "nonimmediate_operand" "0,0") + (match_operand:FPR 2 "general_operand" "f,<Rf>")) + (match_operand:FPR 3 "const0_operand" ""))) + (clobber (match_scratch:FPR 0 "=f,f"))] "s390_match_ccmode (insn, CCSmode) && TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" "@ - sebr\t%0,%2 - seb\t%0,%2" + s<xde>br\t%0,%2 + s<xde>b\t%0,%2" [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fsimps,fsimps")]) - -(define_insn "*subsf3_ibm" - [(set (match_operand:SF 0 "register_operand" "=f,f") - (minus:SF (match_operand:SF 1 "register_operand" "0,0") - (match_operand:SF 2 "general_operand" "f,R"))) - (clobber (reg:CC 33))] + (set_attr "type" "fsimp<mode>")]) + +; sxr, sdr, ser, sx, sd, se +(define_insn "*sub<mode>3_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,<Rf>"))) + (clobber (reg:CC CC_REGNUM))] "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" "@ - ser\t%0,%2 - se\t%0,%2" - [(set_attr "op_type" "RR,RX") - (set_attr "type" "fsimps,fsimps")]) + s<xde>r\t%0,%2 + s<xde>\t%0,%2" + [(set_attr "op_type" "<RRe>,<RXe>") + (set_attr "type" "fsimp<mode>")]) ;; @@ -4226,120 +4222,149 @@ ;; ; -; adddicc instruction pattern(s). +; add(di|si)cc instruction pattern(s). ; -(define_insn "*adddi3_alc_cc" - [(set (reg 33) +; alcr, alc, alcgr, alcg +(define_insn "*add<mode>3_alc_cc" + [(set (reg CC_REGNUM) (compare - (plus:DI (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") - (match_operand:DI 2 "general_operand" "d,m")) - (match_operand:DI 3 "s390_alc_comparison" "")) + (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" "")) (const_int 0))) - (set (match_operand:DI 0 "register_operand" "=d,d") - (plus:DI (plus:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT" + (set (match_operand:GPR 0 "register_operand" "=d,d") + (plus:GPR (plus:GPR (match_dup 1) (match_dup 2)) (match_dup 3)))] + "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH" "@ - alcgr\\t%0,%2 - alcg\\t%0,%2" + alc<g>r\t%0,%2 + alc<g>\t%0,%2" [(set_attr "op_type" "RRE,RXY")]) -(define_insn "*adddi3_alc" - [(set (match_operand:DI 0 "register_operand" "=d,d") - (plus:DI (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") - (match_operand:DI 2 "general_operand" "d,m")) - (match_operand:DI 3 "s390_alc_comparison" ""))) - (clobber (reg:CC 33))] - "TARGET_64BIT" - "@ - alcgr\\t%0,%2 - alcg\\t%0,%2" +; alcr, alc, alcgr, alcg +(define_insn "*add<mode>3_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" ""))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_CPU_ZARCH" + "@ + alc<g>r\t%0,%2 + alc<g>\t%0,%2" [(set_attr "op_type" "RRE,RXY")]) -(define_insn "*subdi3_slb_cc" - [(set (reg 33) +; slbr, slb, slbgr, slbg +(define_insn "*sub<mode>3_slb_cc" + [(set (reg CC_REGNUM) (compare - (minus:DI (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") - (match_operand:DI 2 "general_operand" "d,m")) - (match_operand:DI 3 "s390_slb_comparison" "")) + (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0") + (match_operand:GPR 2 "general_operand" "d,m")) + (match_operand:GPR 3 "s390_slb_comparison" "")) (const_int 0))) - (set (match_operand:DI 0 "register_operand" "=d,d") - (minus:DI (minus:DI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT" + (set (match_operand:GPR 0 "register_operand" "=d,d") + (minus:GPR (minus:GPR (match_dup 1) (match_dup 2)) (match_dup 3)))] + "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH" "@ - slbgr\\t%0,%2 - slbg\\t%0,%2" + slb<g>r\t%0,%2 + slb<g>\t%0,%2" [(set_attr "op_type" "RRE,RXY")]) -(define_insn "*subdi3_slb" - [(set (match_operand:DI 0 "register_operand" "=d,d") - (minus:DI (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") - (match_operand:DI 2 "general_operand" "d,m")) - (match_operand:DI 3 "s390_slb_comparison" ""))) - (clobber (reg:CC 33))] - "TARGET_64BIT" - "@ - slbgr\\t%0,%2 - slbg\\t%0,%2" +; slbr, slb, slbgr, slbg +(define_insn "*sub<mode>3_slb" + [(set (match_operand:GPR 0 "register_operand" "=d,d") + (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0") + (match_operand:GPR 2 "general_operand" "d,m")) + (match_operand:GPR 3 "s390_slb_comparison" ""))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_CPU_ZARCH" + "@ + slb<g>r\t%0,%2 + slb<g>\t%0,%2" [(set_attr "op_type" "RRE,RXY")]) +(define_expand "add<mode>cc" + [(match_operand:GPR 0 "register_operand" "") + (match_operand 1 "comparison_operator" "") + (match_operand:GPR 2 "register_operand" "") + (match_operand:GPR 3 "const_int_operand" "")] + "TARGET_CPU_ZARCH" + "if (!s390_expand_addcc (GET_CODE (operands[1]), + s390_compare_op0, s390_compare_op1, + operands[0], operands[2], + operands[3])) FAIL; DONE;") + ; -; addsicc instruction pattern(s). +; scond instruction pattern(s). ; -(define_insn "*addsi3_alc_cc" - [(set (reg 33) - (compare - (plus:SI (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") - (match_operand:SI 2 "general_operand" "d,m")) - (match_operand:SI 3 "s390_alc_comparison" "")) - (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=d,d") - (plus:SI (plus:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH" - "@ - alcr\\t%0,%2 - alc\\t%0,%2" - [(set_attr "op_type" "RRE,RXY")]) +(define_insn_and_split "*scond<mode>" + [(set (match_operand:GPR 0 "register_operand" "=&d") + (match_operand:GPR 1 "s390_alc_comparison" "")) + (clobber (reg:CC CC_REGNUM))] + "TARGET_CPU_ZARCH" + "#" + "&& 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))) + (clobber (reg:CC CC_REGNUM))])] + "") -(define_insn "*addsi3_alc" - [(set (match_operand:SI 0 "register_operand" "=d,d") - (plus:SI (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") - (match_operand:SI 2 "general_operand" "d,m")) - (match_operand:SI 3 "s390_alc_comparison" ""))) - (clobber (reg:CC 33))] - "TARGET_CPU_ZARCH" - "@ - alcr\\t%0,%2 - alc\\t%0,%2" - [(set_attr "op_type" "RRE,RXY")]) +(define_insn_and_split "*scond<mode>_neg" + [(set (match_operand:GPR 0 "register_operand" "=&d") + (match_operand:GPR 1 "s390_slb_comparison" "")) + (clobber (reg:CC CC_REGNUM))] + "TARGET_CPU_ZARCH" + "#" + "&& reload_completed" + [(set (match_dup 0) (const_int 0)) + (parallel + [(set (match_dup 0) (minus:GPR (minus:GPR (match_dup 0) (match_dup 0)) + (match_dup 1))) + (clobber (reg:CC CC_REGNUM))]) + (parallel + [(set (match_dup 0) (neg:GPR (match_dup 0))) + (clobber (reg:CC CC_REGNUM))])] + "") -(define_insn "*subsi3_slb_cc" - [(set (reg 33) - (compare - (minus:SI (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") - (match_operand:SI 2 "general_operand" "d,m")) - (match_operand:SI 3 "s390_slb_comparison" "")) - (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=d,d") - (minus:SI (minus:SI (match_dup 1) (match_dup 2)) (match_dup 3)))] - "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH" - "@ - slbr\\t%0,%2 - slb\\t%0,%2" - [(set_attr "op_type" "RRE,RXY")]) -(define_insn "*subsi3_slb" - [(set (match_operand:SI 0 "register_operand" "=d,d") - (minus:SI (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") - (match_operand:SI 2 "general_operand" "d,m")) - (match_operand:SI 3 "s390_slb_comparison" ""))) - (clobber (reg:CC 33))] - "TARGET_CPU_ZARCH" - "@ - slbr\\t%0,%2 - slb\\t%0,%2" - [(set_attr "op_type" "RRE,RXY")]) +(define_expand "s<code>" + [(set (match_operand:SI 0 "register_operand" "") + (SCOND (match_dup 0) + (match_dup 0)))] + "TARGET_CPU_ZARCH" + "if (!s390_expand_addcc (<CODE>, s390_compare_op0, s390_compare_op1, + operands[0], const0_rtx, const1_rtx)) FAIL; DONE;") + +(define_expand "seq" + [(parallel + [(set (match_operand:SI 0 "register_operand" "=d") + (match_dup 1)) + (clobber (reg:CC CC_REGNUM))]) + (parallel + [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 1))) + (clobber (reg:CC CC_REGNUM))])] + "" +{ + if (!s390_compare_emitted || GET_MODE (s390_compare_emitted) != CCZ1mode) + FAIL; + operands[1] = s390_emit_compare (NE, s390_compare_op0, s390_compare_op1); + PUT_MODE (operands[1], SImode); +}) + +(define_insn_and_split "*sne" + [(set (match_operand:SI 0 "register_operand" "=d") + (ne:SI (match_operand:CCZ1 1 "register_operand" "0") + (const_int 0))) + (clobber (reg:CC CC_REGNUM))] + "" + "#" + "reload_completed" + [(parallel + [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 28))) + (clobber (reg:CC CC_REGNUM))])]) ;; @@ -4359,7 +4384,7 @@ msgfr\t%0,%2 msgf\t%0,%2" [(set_attr "op_type" "RRE,RXY") - (set_attr "type" "imul")]) + (set_attr "type" "imuldi")]) (define_insn "muldi3" [(set (match_operand:DI 0 "register_operand" "=d,d,d") @@ -4371,7 +4396,7 @@ mghi\t%0,%h2 msg\t%0,%2" [(set_attr "op_type" "RRE,RI,RXY") - (set_attr "type" "imul")]) + (set_attr "type" "imuldi")]) ; ; mulsi3 instruction pattern(s). @@ -4384,7 +4409,7 @@ "" "mh\t%0,%2" [(set_attr "op_type" "RX") - (set_attr "type" "imul")]) + (set_attr "type" "imulhi")]) (define_insn "mulsi3" [(set (match_operand:SI 0 "register_operand" "=d,d,d,d") @@ -4397,7 +4422,7 @@ ms\t%0,%2 msy\t%0,%2" [(set_attr "op_type" "RRE,RI,RX,RXY") - (set_attr "type" "imul")]) + (set_attr "type" "imulsi,imulhi,imulsi,imulsi")]) ; ; mulsidi3 instruction pattern(s). @@ -4414,7 +4439,7 @@ mr\t%0,%2 m\t%0,%2" [(set_attr "op_type" "RR,RX") - (set_attr "type" "imul")]) + (set_attr "type" "imulsi")]) ; ; umulsidi3 instruction pattern(s). @@ -4431,121 +4456,68 @@ mlr\t%0,%2 ml\t%0,%2" [(set_attr "op_type" "RRE,RXY") - (set_attr "type" "imul")]) + (set_attr "type" "imulsi")]) ; -; muldf3 instruction pattern(s). +; mul(df|sf)3 instruction pattern(s). ; -(define_expand "muldf3" - [(set (match_operand:DF 0 "register_operand" "=f,f") - (mult:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0") - (match_operand:DF 2 "general_operand" "f,R")))] +(define_expand "mul<mode>3" + [(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,<Rf>")))] "TARGET_HARD_FLOAT" "") -(define_insn "*muldf3" - [(set (match_operand:DF 0 "register_operand" "=f,f") - (mult:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0") - (match_operand:DF 2 "general_operand" "f,R")))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "@ - mdbr\t%0,%2 - mdb\t%0,%2" - [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fmuld")]) - -(define_insn "*muldf3_ibm" - [(set (match_operand:DF 0 "register_operand" "=f,f") - (mult:DF (match_operand:DF 1 "nonimmediate_operand" "%0,0") - (match_operand:DF 2 "general_operand" "f,R")))] - "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" - "@ - mdr\t%0,%2 - md\t%0,%2" - [(set_attr "op_type" "RR,RX") - (set_attr "type" "fmuld")]) - -(define_insn "*fmadddf" - [(set (match_operand:DF 0 "register_operand" "=f,f") - (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "%f,f") - (match_operand:DF 2 "nonimmediate_operand" "f,R")) - (match_operand:DF 3 "register_operand" "0,0")))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT && TARGET_FUSED_MADD" - "@ - madbr\t%0,%1,%2 - madb\t%0,%1,%2" - [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fmuld")]) - -(define_insn "*fmsubdf" - [(set (match_operand:DF 0 "register_operand" "=f,f") - (minus:DF (mult:DF (match_operand:DF 1 "register_operand" "f,f") - (match_operand:DF 2 "nonimmediate_operand" "f,R")) - (match_operand:DF 3 "register_operand" "0,0")))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT && TARGET_FUSED_MADD" - "@ - msdbr\t%0,%1,%2 - msdb\t%0,%1,%2" - [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fmuld")]) - -; -; mulsf3 instruction pattern(s). -; - -(define_expand "mulsf3" - [(set (match_operand:SF 0 "register_operand" "=f,f") - (mult:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0") - (match_operand:SF 2 "general_operand" "f,R")))] - "TARGET_HARD_FLOAT" - "") - -(define_insn "*mulsf3" - [(set (match_operand:SF 0 "register_operand" "=f,f") - (mult:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0") - (match_operand:SF 2 "general_operand" "f,R")))] +; mxbr mdbr, meebr, mxb, mxb, meeb +(define_insn "*mul<mode>3" + [(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,<Rf>")))] "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" "@ - meebr\t%0,%2 - meeb\t%0,%2" + m<xdee>br\t%0,%2 + m<xdee>b\t%0,%2" [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fmuls")]) + (set_attr "type" "fmul<mode>")]) -(define_insn "*mulsf3_ibm" - [(set (match_operand:SF 0 "register_operand" "=f,f") - (mult:SF (match_operand:SF 1 "nonimmediate_operand" "%0,0") - (match_operand:SF 2 "general_operand" "f,R")))] +; mxr, mdr, mer, mx, md, me +(define_insn "*mul<mode>3_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,<Rf>")))] "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" "@ - mer\t%0,%2 - me\t%0,%2" - [(set_attr "op_type" "RR,RX") - (set_attr "type" "fmuls")]) - -(define_insn "*fmaddsf" - [(set (match_operand:SF 0 "register_operand" "=f,f") - (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "%f,f") - (match_operand:SF 2 "nonimmediate_operand" "f,R")) - (match_operand:SF 3 "register_operand" "0,0")))] + m<xde>r\t%0,%2 + m<xde>\t%0,%2" + [(set_attr "op_type" "<RRe>,<RXe>") + (set_attr "type" "fmul<mode>")]) + +; maxbr, madbr, maebr, maxb, madb, maeb +(define_insn "*fmadd<mode>" + [(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_IEEE_FLOAT && TARGET_FUSED_MADD" "@ - maebr\t%0,%1,%2 - maeb\t%0,%1,%2" + ma<xde>br\t%0,%1,%2 + ma<xde>b\t%0,%1,%2" [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fmuls")]) - -(define_insn "*fmsubsf" - [(set (match_operand:SF 0 "register_operand" "=f,f") - (minus:SF (mult:SF (match_operand:SF 1 "register_operand" "f,f") - (match_operand:SF 2 "nonimmediate_operand" "f,R")) - (match_operand:SF 3 "register_operand" "0,0")))] + (set_attr "type" "fmul<mode>")]) + +; msxbr, msdbr, msebr, msxb, msdb, mseb +(define_insn "*fmsub<mode>" + [(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_IEEE_FLOAT && TARGET_FUSED_MADD" "@ - msebr\t%0,%1,%2 - mseb\t%0,%1,%2" + ms<xde>br\t%0,%1,%2 + ms<xde>b\t%0,%1,%2" [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fmuls")]) + (set_attr "type" "fmul<mode>")]) ;; ;;- Divide and modulo instructions. @@ -4586,14 +4558,12 @@ (define_insn "divmodtidi3" [(set (match_operand:TI 0 "register_operand" "=d,d") (ior:TI - (zero_extend:TI - (div:DI (match_operand:DI 1 "register_operand" "0,0") - (match_operand:DI 2 "general_operand" "d,m"))) (ashift:TI (zero_extend:TI - (mod:DI (match_dup 1) - (match_dup 2))) - (const_int 64))))] + (mod:DI (match_operand:DI 1 "register_operand" "0,0") + (match_operand:DI 2 "general_operand" "d,m"))) + (const_int 64)) + (zero_extend:TI (div:DI (match_dup 1) (match_dup 2)))))] "TARGET_64BIT" "@ dsgr\t%0,%2 @@ -4604,14 +4574,14 @@ (define_insn "divmodtisi3" [(set (match_operand:TI 0 "register_operand" "=d,d") (ior:TI - (zero_extend:TI - (div:DI (match_operand:DI 1 "register_operand" "0,0") - (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "d,m")))) (ashift:TI (zero_extend:TI - (mod:DI (match_dup 1) - (sign_extend:DI (match_dup 2)))) - (const_int 64))))] + (mod:DI (match_operand:DI 1 "register_operand" "0,0") + (sign_extend:DI + (match_operand:SI 2 "nonimmediate_operand" "d,m")))) + (const_int 64)) + (zero_extend:TI + (div:DI (match_dup 1) (sign_extend:DI (match_dup 2))))))] "TARGET_64BIT" "@ dsgfr\t%0,%2 @@ -4637,10 +4607,10 @@ div_equal = gen_rtx_UDIV (DImode, operands[1], operands[2]); mod_equal = gen_rtx_UMOD (DImode, operands[1], operands[2]); equal = gen_rtx_IOR (TImode, - gen_rtx_ZERO_EXTEND (TImode, div_equal), gen_rtx_ASHIFT (TImode, gen_rtx_ZERO_EXTEND (TImode, mod_equal), - GEN_INT (64))); + GEN_INT (64)), + gen_rtx_ZERO_EXTEND (TImode, div_equal)); operands[4] = gen_reg_rtx(TImode); emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[4])); @@ -4663,16 +4633,17 @@ (define_insn "udivmodtidi3" [(set (match_operand:TI 0 "register_operand" "=d,d") - (ior:TI (zero_extend:TI - (truncate:DI - (udiv:TI (match_operand:TI 1 "register_operand" "0,0") - (zero_extend:TI - (match_operand:DI 2 "nonimmediate_operand" "d,m"))))) - (ashift:TI - (zero_extend:TI - (truncate:DI - (umod:TI (match_dup 1) (zero_extend:TI (match_dup 2))))) - (const_int 64))))] + (ior:TI + (ashift:TI + (zero_extend:TI + (truncate:DI + (umod:TI (match_operand:TI 1 "register_operand" "0,0") + (zero_extend:TI + (match_operand:DI 2 "nonimmediate_operand" "d,m"))))) + (const_int 64)) + (zero_extend:TI + (truncate:DI + (udiv:TI (match_dup 1) (zero_extend:TI (match_dup 2)))))))] "TARGET_64BIT" "@ dlgr\t%0,%2 @@ -4698,10 +4669,10 @@ div_equal = gen_rtx_DIV (SImode, operands[1], operands[2]); mod_equal = gen_rtx_MOD (SImode, operands[1], operands[2]); equal = gen_rtx_IOR (DImode, - gen_rtx_ZERO_EXTEND (DImode, div_equal), gen_rtx_ASHIFT (DImode, gen_rtx_ZERO_EXTEND (DImode, mod_equal), - GEN_INT (32))); + GEN_INT (32)), + gen_rtx_ZERO_EXTEND (DImode, div_equal)); operands[4] = gen_reg_rtx(DImode); emit_insn (gen_extendsidi2 (operands[4], operands[1])); @@ -4722,16 +4693,17 @@ (define_insn "divmoddisi3" [(set (match_operand:DI 0 "register_operand" "=d,d") - (ior:DI (zero_extend:DI - (truncate:SI - (div:DI (match_operand:DI 1 "register_operand" "0,0") - (sign_extend:DI - (match_operand:SI 2 "nonimmediate_operand" "d,R"))))) - (ashift:DI - (zero_extend:DI - (truncate:SI - (mod:DI (match_dup 1) (sign_extend:DI (match_dup 2))))) - (const_int 32))))] + (ior:DI + (ashift:DI + (zero_extend:DI + (truncate:SI + (mod:DI (match_operand:DI 1 "register_operand" "0,0") + (sign_extend:DI + (match_operand:SI 2 "nonimmediate_operand" "d,R"))))) + (const_int 32)) + (zero_extend:DI + (truncate:SI + (div:DI (match_dup 1) (sign_extend:DI (match_dup 2)))))))] "!TARGET_64BIT" "@ dr\t%0,%2 @@ -4757,10 +4729,10 @@ div_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]); mod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]); equal = gen_rtx_IOR (DImode, - gen_rtx_ZERO_EXTEND (DImode, div_equal), gen_rtx_ASHIFT (DImode, gen_rtx_ZERO_EXTEND (DImode, mod_equal), - GEN_INT (32))); + GEN_INT (32)), + gen_rtx_ZERO_EXTEND (DImode, div_equal)); operands[4] = gen_reg_rtx(DImode); emit_insn (gen_rtx_CLOBBER (VOIDmode, operands[4])); @@ -4783,16 +4755,17 @@ (define_insn "udivmoddisi3" [(set (match_operand:DI 0 "register_operand" "=d,d") - (ior:DI (zero_extend:DI - (truncate:SI - (udiv:DI (match_operand:DI 1 "register_operand" "0,0") - (zero_extend:DI - (match_operand:SI 2 "nonimmediate_operand" "d,m"))))) - (ashift:DI - (zero_extend:DI - (truncate:SI - (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2))))) - (const_int 32))))] + (ior:DI + (ashift:DI + (zero_extend:DI + (truncate:SI + (umod:DI (match_operand:DI 1 "register_operand" "0,0") + (zero_extend:DI + (match_operand:SI 2 "nonimmediate_operand" "d,m"))))) + (const_int 32)) + (zero_extend:DI + (truncate:SI + (udiv:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))))] "!TARGET_64BIT && TARGET_CPU_ZARCH" "@ dlr\t%0,%2 @@ -4812,10 +4785,10 @@ udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]); umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]); equal = gen_rtx_IOR (DImode, - gen_rtx_ZERO_EXTEND (DImode, udiv_equal), gen_rtx_ASHIFT (DImode, gen_rtx_ZERO_EXTEND (DImode, umod_equal), - GEN_INT (32))); + GEN_INT (32)), + gen_rtx_ZERO_EXTEND (DImode, udiv_equal)); operands[3] = gen_reg_rtx (DImode); @@ -4864,7 +4837,7 @@ emit_move_insn (operands[0], const0_rtx); emit_insn (gen_cmpsi (operands[2], operands[1])); emit_jump_insn (gen_bgtu (label3)); - emit_insn (gen_cmpsi (operands[2], const1_rtx)); + emit_insn (gen_cmpsi (operands[2], const0_rtx)); emit_jump_insn (gen_blt (label2)); emit_insn (gen_cmpsi (operands[2], const1_rtx)); emit_jump_insn (gen_beq (label1)); @@ -4903,10 +4876,10 @@ udiv_equal = gen_rtx_UDIV (SImode, operands[1], operands[2]); umod_equal = gen_rtx_UMOD (SImode, operands[1], operands[2]); equal = gen_rtx_IOR (DImode, - gen_rtx_ZERO_EXTEND (DImode, udiv_equal), gen_rtx_ASHIFT (DImode, gen_rtx_ZERO_EXTEND (DImode, umod_equal), - GEN_INT (32))); + GEN_INT (32)), + gen_rtx_ZERO_EXTEND (DImode, udiv_equal)); operands[3] = gen_reg_rtx (DImode); @@ -4956,7 +4929,7 @@ emit_move_insn(operands[0], operands[1]); emit_insn (gen_cmpsi (operands[2], operands[1])); emit_jump_insn (gen_bgtu (label3)); - emit_insn (gen_cmpsi (operands[2], const1_rtx)); + emit_insn (gen_cmpsi (operands[2], const0_rtx)); emit_jump_insn (gen_blt (label2)); emit_insn (gen_cmpsi (operands[2], const1_rtx)); emit_jump_insn (gen_beq (label1)); @@ -4983,82 +4956,59 @@ }) ; -; divdf3 instruction pattern(s). +; div(df|sf)3 instruction pattern(s). ; -(define_expand "divdf3" - [(set (match_operand:DF 0 "register_operand" "=f,f") - (div:DF (match_operand:DF 1 "register_operand" "0,0") - (match_operand:DF 2 "general_operand" "f,R")))] +(define_expand "div<mode>3" + [(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,<Rf>")))] "TARGET_HARD_FLOAT" "") -(define_insn "*divdf3" - [(set (match_operand:DF 0 "register_operand" "=f,f") - (div:DF (match_operand:DF 1 "register_operand" "0,0") - (match_operand:DF 2 "general_operand" "f,R")))] +; dxbr, ddbr, debr, dxb, ddb, deb +(define_insn "*div<mode>3" + [(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,<Rf>")))] "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" "@ - ddbr\t%0,%2 - ddb\t%0,%2" + d<xde>br\t%0,%2 + d<xde>b\t%0,%2" [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fdivd")]) + (set_attr "type" "fdiv<mode>")]) -(define_insn "*divdf3_ibm" - [(set (match_operand:DF 0 "register_operand" "=f,f") - (div:DF (match_operand:DF 1 "register_operand" "0,0") - (match_operand:DF 2 "general_operand" "f,R")))] +; dxr, ddr, der, dx, dd, de +(define_insn "*div<mode>3_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,<Rf>")))] "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" "@ - ddr\t%0,%2 - dd\t%0,%2" - [(set_attr "op_type" "RR,RX") - (set_attr "type" "fdivd")]) - -; -; divsf3 instruction pattern(s). -; - -(define_expand "divsf3" - [(set (match_operand:SF 0 "register_operand" "=f,f") - (div:SF (match_operand:SF 1 "register_operand" "0,0") - (match_operand:SF 2 "general_operand" "f,R")))] - "TARGET_HARD_FLOAT" - "") - -(define_insn "*divsf3" - [(set (match_operand:SF 0 "register_operand" "=f,f") - (div:SF (match_operand:SF 1 "register_operand" "0,0") - (match_operand:SF 2 "general_operand" "f,R")))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "@ - debr\t%0,%2 - deb\t%0,%2" - [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fdivs")]) - -(define_insn "*divsf3" - [(set (match_operand:SF 0 "register_operand" "=f,f") - (div:SF (match_operand:SF 1 "register_operand" "0,0") - (match_operand:SF 2 "general_operand" "f,R")))] - "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" - "@ - der\t%0,%2 - de\t%0,%2" - [(set_attr "op_type" "RR,RX") - (set_attr "type" "fdivs")]) + d<xde>r\t%0,%2 + d<xde>\t%0,%2" + [(set_attr "op_type" "<RRe>,<RXe>") + (set_attr "type" "fdiv<mode>")]) ;; ;;- And instructions. ;; +(define_expand "and<mode>3" + [(set (match_operand:INT 0 "nonimmediate_operand" "") + (and:INT (match_operand:INT 1 "nonimmediate_operand" "") + (match_operand:INT 2 "general_operand" ""))) + (clobber (reg:CC CC_REGNUM))] + "" + "s390_expand_logical_operator (AND, <MODE>mode, operands); DONE;") + ; ; anddi3 instruction pattern(s). ; (define_insn "*anddi3_cc" - [(set (reg 33) + [(set (reg CC_REGNUM) (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") (match_operand:DI 2 "general_operand" "d,m")) (const_int 0))) @@ -5071,239 +5021,299 @@ [(set_attr "op_type" "RRE,RXY")]) (define_insn "*anddi3_cconly" - [(set (reg 33) + [(set (reg CC_REGNUM) (compare (and: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, CCTmode) && TARGET_64BIT" + "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT + /* Do not steal TM patterns. */ + && s390_single_part (operands[2], DImode, HImode, 0) < 0" "@ ngr\t%0,%2 ng\t%0,%2" [(set_attr "op_type" "RRE,RXY")]) -(define_insn "anddi3" - [(set (match_operand:DI 0 "register_operand" "=d,d,d,d,d,d,d,d") - (and:DI (match_operand:DI 1 "nonimmediate_operand" "d,o,0,0,0,0,0,0") - (match_operand:DI 2 "general_operand" - "M,M,N0HDF,N1HDF,N2HDF,N3HDF,d,m"))) - (clobber (reg:CC 33))] - "TARGET_64BIT" - "@ - # - # - nihh\t%0,%j2 - nihl\t%0,%j2 - nilh\t%0,%j2 - nill\t%0,%j2 - ngr\t%0,%2 - ng\t%0,%2" - [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RRE,RXY")]) - -(define_insn "*anddi3_ss" - [(set (match_operand:DI 0 "s_operand" "=Q") - (and:DI (match_dup 0) - (match_operand:DI 1 "s_imm_operand" "Q"))) - (clobber (reg:CC 33))] - "" - "nc\t%O0(8,%R0),%1" - [(set_attr "op_type" "SS")]) - -(define_insn "*anddi3_ss_inv" - [(set (match_operand:DI 0 "s_operand" "=Q") - (and:DI (match_operand:DI 1 "s_imm_operand" "Q") - (match_dup 0))) - (clobber (reg:CC 33))] - "" - "nc\t%O0(8,%R0),%1" - [(set_attr "op_type" "SS")]) +(define_insn "*anddi3_extimm" + [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,d,d,AQ,Q") + (and:DI (match_operand:DI 1 "nonimmediate_operand" + "%d,o,0,0,0,0,0,0,0,0,0,0") + (match_operand:DI 2 "general_operand" + "M,M,N0HDF,N1HDF,N2HDF,N3HDF,N0SDF,N1SDF,d,m,NxQDF,Q"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_64BIT && TARGET_EXTIMM && s390_logical_operator_ok_p (operands)" + "@ + # + # + nihh\t%0,%j2 + nihl\t%0,%j2 + nilh\t%0,%j2 + nill\t%0,%j2 + nihf\t%0,%m2 + nilf\t%0,%m2 + ngr\t%0,%2 + ng\t%0,%2 + # + #" + [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RIL,RIL,RRE,RXY,SI,SS")]) + +(define_insn "*anddi3" + [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,AQ,Q") + (and:DI (match_operand:DI 1 "nonimmediate_operand" + "%d,o,0,0,0,0,0,0,0,0") + (match_operand:DI 2 "general_operand" + "M,M,N0HDF,N1HDF,N2HDF,N3HDF,d,m,NxQDF,Q"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_64BIT && !TARGET_EXTIMM && s390_logical_operator_ok_p (operands)" + "@ + # + # + nihh\t%0,%j2 + nihl\t%0,%j2 + nilh\t%0,%j2 + nill\t%0,%j2 + ngr\t%0,%2 + ng\t%0,%2 + # + #" + [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RRE,RXY,SI,SS")]) + +(define_split + [(set (match_operand:DI 0 "s_operand" "") + (and:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" ""))) + (clobber (reg:CC CC_REGNUM))] + "reload_completed" + [(parallel + [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1))) + (clobber (reg:CC CC_REGNUM))])] + "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);") + ; ; andsi3 instruction pattern(s). ; (define_insn "*andsi3_cc" - [(set (reg 33) - (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T")) + [(set (reg CC_REGNUM) + (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0") + (match_operand:SI 2 "general_operand" "Os,d,R,T")) (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=d,d,d") + (set (match_operand:SI 0 "register_operand" "=d,d,d,d") (and:SI (match_dup 1) (match_dup 2)))] "s390_match_ccmode(insn, CCTmode)" "@ + nilf\t%0,%o2 nr\t%0,%2 n\t%0,%2 ny\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) + [(set_attr "op_type" "RIL,RR,RX,RXY")]) (define_insn "*andsi3_cconly" - [(set (reg 33) - (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T")) + [(set (reg CC_REGNUM) + (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0") + (match_operand:SI 2 "general_operand" "Os,d,R,T")) (const_int 0))) - (clobber (match_scratch:SI 0 "=d,d,d"))] - "s390_match_ccmode(insn, CCTmode)" + (clobber (match_scratch:SI 0 "=d,d,d,d"))] + "s390_match_ccmode(insn, CCTmode) + /* Do not steal TM patterns. */ + && s390_single_part (operands[2], SImode, HImode, 0) < 0" "@ + nilf\t%0,%o2 nr\t%0,%2 n\t%0,%2 ny\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) - -(define_expand "andsi3" - [(parallel - [(set (match_operand:SI 0 "register_operand" "") - (and:SI (match_operand:SI 1 "nonimmediate_operand" "") - (match_operand:SI 2 "general_operand" ""))) - (clobber (reg:CC 33))])] - "" - "") + [(set_attr "op_type" "RIL,RR,RX,RXY")]) (define_insn "*andsi3_zarch" - [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d,d,d") - (and:SI (match_operand:SI 1 "nonimmediate_operand" "d,o,0,0,0,0,0") - (match_operand:SI 2 "general_operand" "M,M,N0HSF,N1HSF,d,R,T"))) - (clobber (reg:CC 33))] - "TARGET_ZARCH" + [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,AQ,Q") + (and:SI (match_operand:SI 1 "nonimmediate_operand" + "%d,o,0,0,0,0,0,0,0,0") + (match_operand:SI 2 "general_operand" + "M,M,N0HSF,N1HSF,Os,d,R,T,NxQSF,Q"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_ZARCH && s390_logical_operator_ok_p (operands)" "@ # # nilh\t%0,%j2 - nill\t%0,%j2 + nill\t%0,%j2 + nilf\t%0,%o2 nr\t%0,%2 n\t%0,%2 - ny\t%0,%2" - [(set_attr "op_type" "RRE,RXE,RI,RI,RR,RX,RXY")]) + ny\t%0,%2 + # + #" + [(set_attr "op_type" "RRE,RXE,RI,RI,RIL,RR,RX,RXY,SI,SS")]) (define_insn "*andsi3_esa" - [(set (match_operand:SI 0 "register_operand" "=d,d") - (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0") - (match_operand:SI 2 "general_operand" "d,R"))) - (clobber (reg:CC 33))] - "!TARGET_ZARCH" + [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q") + (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0") + (match_operand:SI 2 "general_operand" "d,R,NxQSF,Q"))) + (clobber (reg:CC CC_REGNUM))] + "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)" "@ nr\t%0,%2 - n\t%0,%2" - [(set_attr "op_type" "RR,RX")]) - -(define_insn "*andsi3_ss" - [(set (match_operand:SI 0 "s_operand" "=Q") - (and:SI (match_dup 0) - (match_operand:SI 1 "s_imm_operand" "Q"))) - (clobber (reg:CC 33))] - "" - "nc\t%O0(4,%R0),%1" - [(set_attr "op_type" "SS")]) - -(define_insn "*andsi3_ss_inv" - [(set (match_operand:SI 0 "s_operand" "=Q") - (and:SI (match_operand:SI 1 "s_imm_operand" "Q") - (match_dup 0))) - (clobber (reg:CC 33))] - "" - "nc\t%O0(4,%R0),%1" - [(set_attr "op_type" "SS")]) + n\t%0,%2 + # + #" + [(set_attr "op_type" "RR,RX,SI,SS")]) + +(define_split + [(set (match_operand:SI 0 "s_operand" "") + (and:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" ""))) + (clobber (reg:CC CC_REGNUM))] + "reload_completed" + [(parallel + [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1))) + (clobber (reg:CC CC_REGNUM))])] + "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);") ; ; andhi3 instruction pattern(s). ; -(define_insn "*andhi3_ni" - [(set (match_operand:HI 0 "register_operand" "=d,d") - (and:HI (match_operand:HI 1 "register_operand" "%0,0") - (match_operand:HI 2 "nonmemory_operand" "d,n"))) - (clobber (reg:CC 33))] - "TARGET_ZARCH" +(define_insn "*andhi3_zarch" + [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,AQ,Q") + (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0,0") + (match_operand:HI 2 "general_operand" "d,n,NxQHF,Q"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_ZARCH && s390_logical_operator_ok_p (operands)" "@ nr\t%0,%2 - nill\t%0,%x2" - [(set_attr "op_type" "RR,RI")]) + nill\t%0,%x2 + # + #" + [(set_attr "op_type" "RR,RI,SI,SS")]) -(define_insn "andhi3" - [(set (match_operand:HI 0 "register_operand" "=d") - (and:HI (match_operand:HI 1 "register_operand" "%0") - (match_operand:HI 2 "nonmemory_operand" "d"))) - (clobber (reg:CC 33))] - "" - "nr\t%0,%2" - [(set_attr "op_type" "RR")]) - -(define_insn "*andhi3_ss" - [(set (match_operand:HI 0 "s_operand" "=Q") - (and:HI (match_dup 0) - (match_operand:HI 1 "s_imm_operand" "Q"))) - (clobber (reg:CC 33))] - "" - "nc\t%O0(2,%R0),%1" - [(set_attr "op_type" "SS")]) - -(define_insn "*andhi3_ss_inv" - [(set (match_operand:HI 0 "s_operand" "=Q") - (and:HI (match_operand:HI 1 "s_imm_operand" "Q") - (match_dup 0))) - (clobber (reg:CC 33))] - "" - "nc\t%O0(2,%R0),%1" - [(set_attr "op_type" "SS")]) +(define_insn "*andhi3_esa" + [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q") + (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0") + (match_operand:HI 2 "general_operand" "d,NxQHF,Q"))) + (clobber (reg:CC CC_REGNUM))] + "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)" + "@ + nr\t%0,%2 + # + #" + [(set_attr "op_type" "RR,SI,SS")]) + +(define_split + [(set (match_operand:HI 0 "s_operand" "") + (and:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" ""))) + (clobber (reg:CC CC_REGNUM))] + "reload_completed" + [(parallel + [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1))) + (clobber (reg:CC CC_REGNUM))])] + "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);") ; ; andqi3 instruction pattern(s). ; -(define_insn "*andqi3_ni" - [(set (match_operand:QI 0 "register_operand" "=d,d") - (and:QI (match_operand:QI 1 "register_operand" "%0,0") - (match_operand:QI 2 "nonmemory_operand" "d,n"))) - (clobber (reg:CC 33))] - "TARGET_ZARCH" +(define_insn "*andqi3_zarch" + [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,Q,S,Q") + (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,0,0") + (match_operand:QI 2 "general_operand" "d,n,n,n,Q"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_ZARCH && s390_logical_operator_ok_p (operands)" "@ nr\t%0,%2 - nill\t%0,%b2" - [(set_attr "op_type" "RR,RI")]) - -(define_insn "andqi3" - [(set (match_operand:QI 0 "register_operand" "=d") - (and:QI (match_operand:QI 1 "register_operand" "%0") - (match_operand:QI 2 "nonmemory_operand" "d"))) - (clobber (reg:CC 33))] - "" - "nr\t%0,%2" - [(set_attr "op_type" "RR")]) - -(define_insn "*andqi3_ss" - [(set (match_operand:QI 0 "s_operand" "=Q,S,Q") - (and:QI (match_dup 0) - (match_operand:QI 1 "s_imm_operand" "n,n,Q"))) - (clobber (reg:CC 33))] - "" + nill\t%0,%b2 + ni\t%S0,%b2 + niy\t%S0,%b2 + #" + [(set_attr "op_type" "RR,RI,SI,SIY,SS")]) + +(define_insn "*andqi3_esa" + [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q") + (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") + (match_operand:QI 2 "general_operand" "d,n,Q"))) + (clobber (reg:CC CC_REGNUM))] + "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)" "@ - ni\t%0,%b1 - niy\t%0,%b1 - nc\t%O0(1,%R0),%1" - [(set_attr "op_type" "SI,SIY,SS")]) + nr\t%0,%2 + ni\t%S0,%b2 + #" + [(set_attr "op_type" "RR,SI,SS")]) -(define_insn "*andqi3_ss_inv" - [(set (match_operand:QI 0 "s_operand" "=Q,S,Q") - (and:QI (match_operand:QI 1 "s_imm_operand" "n,n,Q") - (match_dup 0))) - (clobber (reg:CC 33))] - "" - "@ - ni\t%0,%b1 - niy\t%0,%b1 - nc\t%O0(1,%R0),%1" - [(set_attr "op_type" "SI,SIY,SS")]) +; +; Block and (NC) patterns. +; + +(define_insn "*nc" + [(set (match_operand:BLK 0 "memory_operand" "=Q") + (and:BLK (match_dup 0) + (match_operand:BLK 1 "memory_operand" "Q"))) + (use (match_operand 2 "const_int_operand" "n")) + (clobber (reg:CC CC_REGNUM))] + "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256" + "nc\t%O0(%2,%R0),%S1" + [(set_attr "op_type" "SS")]) + +(define_split + [(set (match_operand 0 "memory_operand" "") + (and (match_dup 0) + (match_operand 1 "memory_operand" ""))) + (clobber (reg:CC CC_REGNUM))] + "reload_completed + && GET_MODE (operands[0]) == GET_MODE (operands[1]) + && GET_MODE_SIZE (GET_MODE (operands[0])) > 0" + [(parallel + [(set (match_dup 0) (and:BLK (match_dup 0) (match_dup 1))) + (use (match_dup 2)) + (clobber (reg:CC CC_REGNUM))])] +{ + operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0]))); + operands[0] = adjust_address (operands[0], BLKmode, 0); + operands[1] = adjust_address (operands[1], BLKmode, 0); +}) + +(define_peephole2 + [(parallel + [(set (match_operand:BLK 0 "memory_operand" "") + (and:BLK (match_dup 0) + (match_operand:BLK 1 "memory_operand" ""))) + (use (match_operand 2 "const_int_operand" "")) + (clobber (reg:CC CC_REGNUM))]) + (parallel + [(set (match_operand:BLK 3 "memory_operand" "") + (and:BLK (match_dup 3) + (match_operand:BLK 4 "memory_operand" ""))) + (use (match_operand 5 "const_int_operand" "")) + (clobber (reg:CC CC_REGNUM))])] + "s390_offset_p (operands[0], operands[3], operands[2]) + && s390_offset_p (operands[1], operands[4], operands[2]) + && !s390_overlap_p (operands[0], operands[1], + INTVAL (operands[2]) + INTVAL (operands[5])) + && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256" + [(parallel + [(set (match_dup 6) (and:BLK (match_dup 6) (match_dup 7))) + (use (match_dup 8)) + (clobber (reg:CC CC_REGNUM))])] + "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0)); + operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0)); + operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));") ;; ;;- Bit set (inclusive or) instructions. ;; +(define_expand "ior<mode>3" + [(set (match_operand:INT 0 "nonimmediate_operand" "") + (ior:INT (match_operand:INT 1 "nonimmediate_operand" "") + (match_operand:INT 2 "general_operand" ""))) + (clobber (reg:CC CC_REGNUM))] + "" + "s390_expand_logical_operator (IOR, <MODE>mode, operands); DONE;") + ; ; iordi3 instruction pattern(s). ; (define_insn "*iordi3_cc" - [(set (reg 33) + [(set (reg CC_REGNUM) (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") (match_operand:DI 2 "general_operand" "d,m")) (const_int 0))) @@ -5316,7 +5326,7 @@ [(set_attr "op_type" "RRE,RXY")]) (define_insn "*iordi3_cconly" - [(set (reg 33) + [(set (reg CC_REGNUM) (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") (match_operand:DI 2 "general_operand" "d,m")) (const_int 0))) @@ -5327,223 +5337,273 @@ og\t%0,%2" [(set_attr "op_type" "RRE,RXY")]) -(define_insn "iordi3" - [(set (match_operand:DI 0 "register_operand" "=d,d,d,d,d,d") - (ior:DI (match_operand:DI 1 "nonimmediate_operand" "0,0,0,0,0,0") - (match_operand:DI 2 "general_operand" "N0HD0,N1HD0,N2HD0,N3HD0,d,m"))) - (clobber (reg:CC 33))] - "TARGET_64BIT" +(define_insn "*iordi3_extimm" + [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,AQ,Q") + (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0,0,0,0,0,0,0") + (match_operand:DI 2 "general_operand" + "N0HD0,N1HD0,N2HD0,N3HD0,N0SD0,N1SD0,d,m,NxQD0,Q"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_64BIT && TARGET_EXTIMM && s390_logical_operator_ok_p (operands)" "@ oihh\t%0,%i2 oihl\t%0,%i2 oilh\t%0,%i2 oill\t%0,%i2 + oihf\t%0,%k2 + oilf\t%0,%k2 ogr\t%0,%2 - og\t%0,%2" - [(set_attr "op_type" "RI,RI,RI,RI,RRE,RXY")]) + og\t%0,%2 + # + #" + [(set_attr "op_type" "RI,RI,RI,RI,RIL,RIL,RRE,RXY,SI,SS")]) -(define_insn "*iordi3_ss" - [(set (match_operand:DI 0 "s_operand" "=Q") - (ior:DI (match_dup 0) - (match_operand:DI 1 "s_imm_operand" "Q"))) - (clobber (reg:CC 33))] - "" - "oc\t%O0(8,%R0),%1" - [(set_attr "op_type" "SS")]) - -(define_insn "*iordi3_ss_inv" - [(set (match_operand:DI 0 "s_operand" "=Q") - (ior:DI (match_operand:DI 1 "s_imm_operand" "Q") - (match_dup 0))) - (clobber (reg:CC 33))] - "" - "oc\t%O0(8,%R0),%1" - [(set_attr "op_type" "SS")]) +(define_insn "*iordi3" + [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,AQ,Q") + (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0,0,0,0,0") + (match_operand:DI 2 "general_operand" + "N0HD0,N1HD0,N2HD0,N3HD0,d,m,NxQD0,Q"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_64BIT && !TARGET_EXTIMM && s390_logical_operator_ok_p (operands)" + "@ + oihh\t%0,%i2 + oihl\t%0,%i2 + oilh\t%0,%i2 + oill\t%0,%i2 + ogr\t%0,%2 + og\t%0,%2 + # + #" + [(set_attr "op_type" "RI,RI,RI,RI,RRE,RXY,SI,SS")]) + +(define_split + [(set (match_operand:DI 0 "s_operand" "") + (ior:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" ""))) + (clobber (reg:CC CC_REGNUM))] + "reload_completed" + [(parallel + [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1))) + (clobber (reg:CC CC_REGNUM))])] + "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);") ; ; iorsi3 instruction pattern(s). ; (define_insn "*iorsi3_cc" - [(set (reg 33) - (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T")) + [(set (reg CC_REGNUM) + (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0") + (match_operand:SI 2 "general_operand" "Os,d,R,T")) (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=d,d,d") + (set (match_operand:SI 0 "register_operand" "=d,d,d,d") (ior:SI (match_dup 1) (match_dup 2)))] "s390_match_ccmode(insn, CCTmode)" "@ + oilf\t%0,%o2 or\t%0,%2 o\t%0,%2 oy\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) + [(set_attr "op_type" "RIL,RR,RX,RXY")]) (define_insn "*iorsi3_cconly" - [(set (reg 33) - (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T")) + [(set (reg CC_REGNUM) + (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0") + (match_operand:SI 2 "general_operand" "Os,d,R,T")) (const_int 0))) - (clobber (match_scratch:SI 0 "=d,d,d"))] + (clobber (match_scratch:SI 0 "=d,d,d,d"))] "s390_match_ccmode(insn, CCTmode)" "@ + oilf\t%0,%o2 or\t%0,%2 o\t%0,%2 oy\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) + [(set_attr "op_type" "RIL,RR,RX,RXY")]) -(define_expand "iorsi3" - [(parallel - [(set (match_operand:SI 0 "register_operand" "") - (ior:SI (match_operand:SI 1 "nonimmediate_operand" "") - (match_operand:SI 2 "general_operand" ""))) - (clobber (reg:CC 33))])] - "" - "") - -(define_insn "iorsi3_zarch" - [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d") - (ior:SI (match_operand:SI 1 "nonimmediate_operand" "0,0,0,0,0") - (match_operand:SI 2 "general_operand" "N0HS0,N1HS0,d,R,T"))) - (clobber (reg:CC 33))] - "TARGET_ZARCH" +(define_insn "*iorsi3_zarch" + [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,AQ,Q") + (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0,0,0,0") + (match_operand:SI 2 "general_operand" "N0HS0,N1HS0,Os,d,R,T,NxQS0,Q"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_ZARCH && s390_logical_operator_ok_p (operands)" "@ oilh\t%0,%i2 oill\t%0,%i2 + oilf\t%0,%o2 or\t%0,%2 o\t%0,%2 - oy\t%0,%2" - [(set_attr "op_type" "RI,RI,RR,RX,RXY")]) + oy\t%0,%2 + # + #" + [(set_attr "op_type" "RI,RI,RIL,RR,RX,RXY,SI,SS")]) -(define_insn "iorsi3_esa" - [(set (match_operand:SI 0 "register_operand" "=d,d") - (ior:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") - (match_operand:SI 2 "general_operand" "d,R"))) - (clobber (reg:CC 33))] - "!TARGET_ZARCH" +(define_insn "*iorsi3_esa" + [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q") + (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0") + (match_operand:SI 2 "general_operand" "d,R,NxQS0,Q"))) + (clobber (reg:CC CC_REGNUM))] + "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)" "@ or\t%0,%2 - o\t%0,%2" - [(set_attr "op_type" "RR,RX")]) - -(define_insn "*iorsi3_ss" - [(set (match_operand:SI 0 "s_operand" "=Q") - (ior:SI (match_dup 0) - (match_operand:SI 1 "s_imm_operand" "Q"))) - (clobber (reg:CC 33))] - "" - "oc\t%O0(4,%R0),%1" - [(set_attr "op_type" "SS")]) - -(define_insn "*iorsi3_ss_inv" - [(set (match_operand:SI 0 "s_operand" "=Q") - (ior:SI (match_operand:SI 1 "s_imm_operand" "Q") - (match_dup 0))) - (clobber (reg:CC 33))] - "" - "oc\t%O0(4,%R0),%1" - [(set_attr "op_type" "SS")]) + o\t%0,%2 + # + #" + [(set_attr "op_type" "RR,RX,SI,SS")]) + +(define_split + [(set (match_operand:SI 0 "s_operand" "") + (ior:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" ""))) + (clobber (reg:CC CC_REGNUM))] + "reload_completed" + [(parallel + [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1))) + (clobber (reg:CC CC_REGNUM))])] + "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);") ; ; iorhi3 instruction pattern(s). ; -(define_insn "*iorhi3_oi" - [(set (match_operand:HI 0 "register_operand" "=d,d") - (ior:HI (match_operand:HI 1 "register_operand" "%0,0") - (match_operand:HI 2 "nonmemory_operand" "d,n"))) - (clobber (reg:CC 33))] - "TARGET_ZARCH" +(define_insn "*iorhi3_zarch" + [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,AQ,Q") + (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0,0") + (match_operand:HI 2 "general_operand" "d,n,NxQH0,Q"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_ZARCH && s390_logical_operator_ok_p (operands)" "@ or\t%0,%2 - oill\t%0,%x2" - [(set_attr "op_type" "RR,RI")]) + oill\t%0,%x2 + # + #" + [(set_attr "op_type" "RR,RI,SI,SS")]) -(define_insn "iorhi3" - [(set (match_operand:HI 0 "register_operand" "=d") - (ior:HI (match_operand:HI 1 "register_operand" "%0") - (match_operand:HI 2 "nonmemory_operand" "d"))) - (clobber (reg:CC 33))] - "" - "or\t%0,%2" - [(set_attr "op_type" "RR")]) - -(define_insn "*iorhi3_ss" - [(set (match_operand:HI 0 "s_operand" "=Q") - (ior:HI (match_dup 0) - (match_operand:HI 1 "s_imm_operand" "Q"))) - (clobber (reg:CC 33))] - "" - "oc\t%O0(2,%R0),%1" - [(set_attr "op_type" "SS")]) - -(define_insn "*iorhi3_ss_inv" - [(set (match_operand:HI 0 "s_operand" "=Q") - (ior:HI (match_operand:HI 1 "s_imm_operand" "Q") - (match_dup 0))) - (clobber (reg:CC 33))] - "" - "oc\t%O0(2,%R0),%1" - [(set_attr "op_type" "SS")]) +(define_insn "*iorhi3_esa" + [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q") + (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0") + (match_operand:HI 2 "general_operand" "d,NxQH0,Q"))) + (clobber (reg:CC CC_REGNUM))] + "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)" + "@ + or\t%0,%2 + # + #" + [(set_attr "op_type" "RR,SI,SS")]) + +(define_split + [(set (match_operand:HI 0 "s_operand" "") + (ior:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" ""))) + (clobber (reg:CC CC_REGNUM))] + "reload_completed" + [(parallel + [(set (match_dup 0) (ior:QI (match_dup 0) (match_dup 1))) + (clobber (reg:CC CC_REGNUM))])] + "s390_narrow_logical_operator (IOR, &operands[0], &operands[1]);") ; ; iorqi3 instruction pattern(s). ; -(define_insn "*iorqi3_oi" - [(set (match_operand:QI 0 "register_operand" "=d,d") - (ior:QI (match_operand:QI 1 "register_operand" "%0,0") - (match_operand:QI 2 "nonmemory_operand" "d,n"))) - (clobber (reg:CC 33))] - "TARGET_ZARCH" +(define_insn "*iorqi3_zarch" + [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,Q,S,Q") + (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,0,0") + (match_operand:QI 2 "general_operand" "d,n,n,n,Q"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_ZARCH && s390_logical_operator_ok_p (operands)" "@ or\t%0,%2 - oill\t%0,%b2" - [(set_attr "op_type" "RR,RI")]) - -(define_insn "iorqi3" - [(set (match_operand:QI 0 "register_operand" "=d") - (ior:QI (match_operand:QI 1 "register_operand" "%0") - (match_operand:QI 2 "nonmemory_operand" "d"))) - (clobber (reg:CC 33))] - "" - "or\t%0,%2" - [(set_attr "op_type" "RR")]) - -(define_insn "*iorqi3_ss" - [(set (match_operand:QI 0 "s_operand" "=Q,S,Q") - (ior:QI (match_dup 0) - (match_operand:QI 1 "s_imm_operand" "n,n,Q"))) - (clobber (reg:CC 33))] - "" + oill\t%0,%b2 + oi\t%S0,%b2 + oiy\t%S0,%b2 + #" + [(set_attr "op_type" "RR,RI,SI,SIY,SS")]) + +(define_insn "*iorqi3_esa" + [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q") + (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0") + (match_operand:QI 2 "general_operand" "d,n,Q"))) + (clobber (reg:CC CC_REGNUM))] + "!TARGET_ZARCH && s390_logical_operator_ok_p (operands)" "@ - oi\t%0,%b1 - oiy\t%0,%b1 - oc\t%O0(1,%R0),%1" - [(set_attr "op_type" "SI,SIY,SS")]) + or\t%0,%2 + oi\t%S0,%b2 + #" + [(set_attr "op_type" "RR,SI,SS")]) -(define_insn "*iorqi3_ss_inv" - [(set (match_operand:QI 0 "s_operand" "=Q,S,Q") - (ior:QI (match_operand:QI 1 "s_imm_operand" "n,n,Q") - (match_dup 0))) - (clobber (reg:CC 33))] - "" - "@ - oi\t%0,%b1 - oiy\t%0,%b1 - oc\t%O0(1,%R0),%1" - [(set_attr "op_type" "SI,SIY,SS")]) +; +; Block inclusive or (OC) patterns. +; + +(define_insn "*oc" + [(set (match_operand:BLK 0 "memory_operand" "=Q") + (ior:BLK (match_dup 0) + (match_operand:BLK 1 "memory_operand" "Q"))) + (use (match_operand 2 "const_int_operand" "n")) + (clobber (reg:CC CC_REGNUM))] + "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256" + "oc\t%O0(%2,%R0),%S1" + [(set_attr "op_type" "SS")]) + +(define_split + [(set (match_operand 0 "memory_operand" "") + (ior (match_dup 0) + (match_operand 1 "memory_operand" ""))) + (clobber (reg:CC CC_REGNUM))] + "reload_completed + && GET_MODE (operands[0]) == GET_MODE (operands[1]) + && GET_MODE_SIZE (GET_MODE (operands[0])) > 0" + [(parallel + [(set (match_dup 0) (ior:BLK (match_dup 0) (match_dup 1))) + (use (match_dup 2)) + (clobber (reg:CC CC_REGNUM))])] +{ + operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0]))); + operands[0] = adjust_address (operands[0], BLKmode, 0); + operands[1] = adjust_address (operands[1], BLKmode, 0); +}) + +(define_peephole2 + [(parallel + [(set (match_operand:BLK 0 "memory_operand" "") + (ior:BLK (match_dup 0) + (match_operand:BLK 1 "memory_operand" ""))) + (use (match_operand 2 "const_int_operand" "")) + (clobber (reg:CC CC_REGNUM))]) + (parallel + [(set (match_operand:BLK 3 "memory_operand" "") + (ior:BLK (match_dup 3) + (match_operand:BLK 4 "memory_operand" ""))) + (use (match_operand 5 "const_int_operand" "")) + (clobber (reg:CC CC_REGNUM))])] + "s390_offset_p (operands[0], operands[3], operands[2]) + && s390_offset_p (operands[1], operands[4], operands[2]) + && !s390_overlap_p (operands[0], operands[1], + INTVAL (operands[2]) + INTVAL (operands[5])) + && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256" + [(parallel + [(set (match_dup 6) (ior:BLK (match_dup 6) (match_dup 7))) + (use (match_dup 8)) + (clobber (reg:CC CC_REGNUM))])] + "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0)); + operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0)); + operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));") ;; ;;- Xor instructions. ;; +(define_expand "xor<mode>3" + [(set (match_operand:INT 0 "nonimmediate_operand" "") + (xor:INT (match_operand:INT 1 "nonimmediate_operand" "") + (match_operand:INT 2 "general_operand" ""))) + (clobber (reg:CC CC_REGNUM))] + "" + "s390_expand_logical_operator (XOR, <MODE>mode, operands); DONE;") + ; ; xordi3 instruction pattern(s). ; (define_insn "*xordi3_cc" - [(set (reg 33) + [(set (reg CC_REGNUM) (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") (match_operand:DI 2 "general_operand" "d,m")) (const_int 0))) @@ -5556,7 +5616,7 @@ [(set_attr "op_type" "RRE,RXY")]) (define_insn "*xordi3_cconly" - [(set (reg 33) + [(set (reg CC_REGNUM) (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") (match_operand:DI 2 "general_operand" "d,m")) (const_int 0))) @@ -5567,163 +5627,237 @@ xr\t%0,%2" [(set_attr "op_type" "RRE,RXY")]) -(define_insn "xordi3" - [(set (match_operand:DI 0 "register_operand" "=d,d") - (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") - (match_operand:DI 2 "general_operand" "d,m"))) - (clobber (reg:CC 33))] - "TARGET_64BIT" +(define_insn "*xordi3_extimm" + [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,AQ,Q") + (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0,0,0") + (match_operand:DI 2 "general_operand" "N0SD0,N1SD0,d,m,NxQD0,Q"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_64BIT && TARGET_EXTIMM && s390_logical_operator_ok_p (operands)" "@ + xihf\t%0,%k2 + xilf\t%0,%k2 xgr\t%0,%2 - xg\t%0,%2" - [(set_attr "op_type" "RRE,RXY")]) + xg\t%0,%2 + # + #" + [(set_attr "op_type" "RIL,RIL,RRE,RXY,SI,SS")]) -(define_insn "*xordi3_ss" - [(set (match_operand:DI 0 "s_operand" "=Q") - (xor:DI (match_dup 0) - (match_operand:DI 1 "s_imm_operand" "Q"))) - (clobber (reg:CC 33))] - "" - "xc\t%O0(8,%R0),%1" - [(set_attr "op_type" "SS")]) - -(define_insn "*xordi3_ss_inv" - [(set (match_operand:DI 0 "s_operand" "=Q") - (xor:DI (match_operand:DI 1 "s_imm_operand" "Q") - (match_dup 0))) - (clobber (reg:CC 33))] - "" - "xc\t%O0(8,%R0),%1" - [(set_attr "op_type" "SS")]) +(define_insn "*xordi3" + [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,AQ,Q") + (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0") + (match_operand:DI 2 "general_operand" "d,m,NxQD0,Q"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_64BIT && !TARGET_EXTIMM && s390_logical_operator_ok_p (operands)" + "@ + xgr\t%0,%2 + xg\t%0,%2 + # + #" + [(set_attr "op_type" "RRE,RXY,SI,SS")]) + +(define_split + [(set (match_operand:DI 0 "s_operand" "") + (xor:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" ""))) + (clobber (reg:CC CC_REGNUM))] + "reload_completed" + [(parallel + [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1))) + (clobber (reg:CC CC_REGNUM))])] + "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);") ; ; xorsi3 instruction pattern(s). ; (define_insn "*xorsi3_cc" - [(set (reg 33) - (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T")) + [(set (reg CC_REGNUM) + (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0") + (match_operand:SI 2 "general_operand" "Os,d,R,T")) (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=d,d,d") + (set (match_operand:SI 0 "register_operand" "=d,d,d,d") (xor:SI (match_dup 1) (match_dup 2)))] "s390_match_ccmode(insn, CCTmode)" "@ + xilf\t%0,%o2 xr\t%0,%2 x\t%0,%2 xy\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) + [(set_attr "op_type" "RIL,RR,RX,RXY")]) (define_insn "*xorsi3_cconly" - [(set (reg 33) - (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T")) + [(set (reg CC_REGNUM) + (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0") + (match_operand:SI 2 "general_operand" "Os,d,R,T")) (const_int 0))) - (clobber (match_scratch:SI 0 "=d,d,d"))] + (clobber (match_scratch:SI 0 "=d,d,d,d"))] "s390_match_ccmode(insn, CCTmode)" "@ + xilf\t%0,%o2 xr\t%0,%2 x\t%0,%2 xy\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) + [(set_attr "op_type" "RIL,RR,RX,RXY")]) -(define_insn "xorsi3" - [(set (match_operand:SI 0 "register_operand" "=d,d,d") - (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T"))) - (clobber (reg:CC 33))] - "" +(define_insn "*xorsi3" + [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,AQ,Q") + (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0,0") + (match_operand:SI 2 "general_operand" "Os,d,R,T,NxQS0,Q"))) + (clobber (reg:CC CC_REGNUM))] + "s390_logical_operator_ok_p (operands)" "@ + xilf\t%0,%o2 xr\t%0,%2 x\t%0,%2 - xy\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) + xy\t%0,%2 + # + #" + [(set_attr "op_type" "RIL,RR,RX,RXY,SI,SS")]) -(define_insn "*xorsi3_ss" - [(set (match_operand:SI 0 "s_operand" "=Q") - (xor:SI (match_dup 0) - (match_operand:SI 1 "s_imm_operand" "Q"))) - (clobber (reg:CC 33))] - "" - "xc\t%O0(4,%R0),%1" - [(set_attr "op_type" "SS")]) - -(define_insn "*xorsi3_ss_inv" - [(set (match_operand:SI 0 "s_operand" "=Q") - (xor:SI (match_operand:SI 1 "s_imm_operand" "Q") - (match_dup 0))) - (clobber (reg:CC 33))] - "" - "xc\t%O0(4,%R0),%1" - [(set_attr "op_type" "SS")]) +(define_split + [(set (match_operand:SI 0 "s_operand" "") + (xor:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" ""))) + (clobber (reg:CC CC_REGNUM))] + "reload_completed" + [(parallel + [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1))) + (clobber (reg:CC CC_REGNUM))])] + "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);") ; ; xorhi3 instruction pattern(s). ; -(define_insn "xorhi3" - [(set (match_operand:HI 0 "register_operand" "=d") - (xor:HI (match_operand:HI 1 "register_operand" "%0") - (match_operand:HI 2 "nonmemory_operand" "d"))) - (clobber (reg:CC 33))] - "" - "xr\t%0,%2" - [(set_attr "op_type" "RR")]) - -(define_insn "*xorhi3_ss" - [(set (match_operand:HI 0 "s_operand" "=Q") - (xor:HI (match_dup 0) - (match_operand:HI 1 "s_imm_operand" "Q"))) - (clobber (reg:CC 33))] - "" - "xc\t%O0(2,%R0),%1" - [(set_attr "op_type" "SS")]) - -(define_insn "*xorhi3_ss_inv" - [(set (match_operand:HI 0 "s_operand" "=Q") - (xor:HI (match_operand:HI 1 "s_imm_operand" "Q") - (match_dup 0))) - (clobber (reg:CC 33))] - "" - "xc\t%O0(2,%R0),%1" - [(set_attr "op_type" "SS")]) +(define_insn "*xorhi3" + [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,AQ,Q") + (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0,0") + (match_operand:HI 2 "general_operand" "Os,d,NxQH0,Q"))) + (clobber (reg:CC CC_REGNUM))] + "s390_logical_operator_ok_p (operands)" + "@ + xilf\t%0,%x2 + xr\t%0,%2 + # + #" + [(set_attr "op_type" "RIL,RR,SI,SS")]) + +(define_split + [(set (match_operand:HI 0 "s_operand" "") + (xor:HI (match_dup 0) (match_operand:HI 1 "immediate_operand" ""))) + (clobber (reg:CC CC_REGNUM))] + "reload_completed" + [(parallel + [(set (match_dup 0) (xor:QI (match_dup 0) (match_dup 1))) + (clobber (reg:CC CC_REGNUM))])] + "s390_narrow_logical_operator (XOR, &operands[0], &operands[1]);") ; ; xorqi3 instruction pattern(s). ; -(define_insn "xorqi3" - [(set (match_operand:QI 0 "register_operand" "=d") - (xor:QI (match_operand:QI 1 "register_operand" "%0") - (match_operand:QI 2 "nonmemory_operand" "d"))) - (clobber (reg:CC 33))] - "" - "xr\t%0,%2" - [(set_attr "op_type" "RR")]) - -(define_insn "*xorqi3_ss" - [(set (match_operand:QI 0 "s_operand" "=Q,S,Q") - (xor:QI (match_dup 0) - (match_operand:QI 1 "s_imm_operand" "n,n,Q"))) - (clobber (reg:CC 33))] - "" +(define_insn "*xorqi3" + [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,Q,S,Q") + (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,0,0") + (match_operand:QI 2 "general_operand" "Os,d,n,n,Q"))) + (clobber (reg:CC CC_REGNUM))] + "s390_logical_operator_ok_p (operands)" "@ - xi\t%0,%b1 - xiy\t%0,%b1 - xc\t%O0(1,%R0),%1" - [(set_attr "op_type" "SI,SIY,SS")]) + xilf\t%0,%b2 + xr\t%0,%2 + xi\t%S0,%b2 + xiy\t%S0,%b2 + #" + [(set_attr "op_type" "RIL,RR,SI,SIY,SS")]) -(define_insn "*xorqi3_ss_inv" - [(set (match_operand:QI 0 "s_operand" "=Q,S,Q") - (xor:QI (match_operand:QI 1 "s_imm_operand" "n,n,Q") - (match_dup 0))) - (clobber (reg:CC 33))] - "" - "@ - xi\t%0,%b1 - xiy\t%0,%b1 - xc\t%O0(1,%R0),%1" - [(set_attr "op_type" "SI,SIY,SS")]) +; +; Block exclusive or (XC) patterns. +; + +(define_insn "*xc" + [(set (match_operand:BLK 0 "memory_operand" "=Q") + (xor:BLK (match_dup 0) + (match_operand:BLK 1 "memory_operand" "Q"))) + (use (match_operand 2 "const_int_operand" "n")) + (clobber (reg:CC CC_REGNUM))] + "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256" + "xc\t%O0(%2,%R0),%S1" + [(set_attr "op_type" "SS")]) + +(define_split + [(set (match_operand 0 "memory_operand" "") + (xor (match_dup 0) + (match_operand 1 "memory_operand" ""))) + (clobber (reg:CC CC_REGNUM))] + "reload_completed + && GET_MODE (operands[0]) == GET_MODE (operands[1]) + && GET_MODE_SIZE (GET_MODE (operands[0])) > 0" + [(parallel + [(set (match_dup 0) (xor:BLK (match_dup 0) (match_dup 1))) + (use (match_dup 2)) + (clobber (reg:CC CC_REGNUM))])] +{ + operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0]))); + operands[0] = adjust_address (operands[0], BLKmode, 0); + operands[1] = adjust_address (operands[1], BLKmode, 0); +}) + +(define_peephole2 + [(parallel + [(set (match_operand:BLK 0 "memory_operand" "") + (xor:BLK (match_dup 0) + (match_operand:BLK 1 "memory_operand" ""))) + (use (match_operand 2 "const_int_operand" "")) + (clobber (reg:CC CC_REGNUM))]) + (parallel + [(set (match_operand:BLK 3 "memory_operand" "") + (xor:BLK (match_dup 3) + (match_operand:BLK 4 "memory_operand" ""))) + (use (match_operand 5 "const_int_operand" "")) + (clobber (reg:CC CC_REGNUM))])] + "s390_offset_p (operands[0], operands[3], operands[2]) + && s390_offset_p (operands[1], operands[4], operands[2]) + && !s390_overlap_p (operands[0], operands[1], + INTVAL (operands[2]) + INTVAL (operands[5])) + && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256" + [(parallel + [(set (match_dup 6) (xor:BLK (match_dup 6) (match_dup 7))) + (use (match_dup 8)) + (clobber (reg:CC CC_REGNUM))])] + "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0)); + operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0)); + operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));") + +; +; Block xor (XC) patterns with src == dest. +; + +(define_insn "*xc_zero" + [(set (match_operand:BLK 0 "memory_operand" "=Q") + (const_int 0)) + (use (match_operand 1 "const_int_operand" "n")) + (clobber (reg:CC CC_REGNUM))] + "INTVAL (operands[1]) >= 1 && INTVAL (operands[1]) <= 256" + "xc\t%O0(%1,%R0),%S0" + [(set_attr "op_type" "SS")]) + +(define_peephole2 + [(parallel + [(set (match_operand:BLK 0 "memory_operand" "") + (const_int 0)) + (use (match_operand 1 "const_int_operand" "")) + (clobber (reg:CC CC_REGNUM))]) + (parallel + [(set (match_operand:BLK 2 "memory_operand" "") + (const_int 0)) + (use (match_operand 3 "const_int_operand" "")) + (clobber (reg:CC CC_REGNUM))])] + "s390_offset_p (operands[0], operands[2], operands[1]) + && INTVAL (operands[1]) + INTVAL (operands[3]) <= 256" + [(parallel + [(set (match_dup 4) (const_int 0)) + (use (match_dup 5)) + (clobber (reg:CC CC_REGNUM))])] + "operands[4] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0)); + operands[5] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[3]));") ;; @@ -5731,116 +5865,149 @@ ;; ; -; negdi2 instruction pattern(s). +; neg(di|si)2 instruction pattern(s). ; -(define_expand "negdi2" +(define_expand "neg<mode>2" [(parallel - [(set (match_operand:DI 0 "register_operand" "=d") - (neg:DI (match_operand:DI 1 "register_operand" "d"))) - (clobber (reg:CC 33))])] + [(set (match_operand:DSI 0 "register_operand" "=d") + (neg:DSI (match_operand:DSI 1 "register_operand" "d"))) + (clobber (reg:CC CC_REGNUM))])] "" "") -(define_insn "*negdi2_64" +(define_insn "*negdi2_sign_cc" + [(set (reg CC_REGNUM) + (compare (neg:DI (ashiftrt:DI (ashift:DI (subreg:DI + (match_operand:SI 1 "register_operand" "d") 0) + (const_int 32)) (const_int 32))) + (const_int 0))) + (set (match_operand:DI 0 "register_operand" "=d") + (neg:DI (sign_extend:DI (match_dup 1))))] + "TARGET_64BIT && s390_match_ccmode (insn, CCAmode)" + "lcgfr\t%0,%1" + [(set_attr "op_type" "RRE")]) + +(define_insn "*negdi2_sign" [(set (match_operand:DI 0 "register_operand" "=d") - (neg:DI (match_operand:DI 1 "register_operand" "d"))) - (clobber (reg:CC 33))] + (neg:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d")))) + (clobber (reg:CC CC_REGNUM))] "TARGET_64BIT" - "lcgr\t%0,%1" - [(set_attr "op_type" "RR")]) + "lcgfr\t%0,%1" + [(set_attr "op_type" "RRE")]) -(define_insn "*negdi2_31" +; lcr, lcgr +(define_insn "*neg<mode>2_cc" + [(set (reg CC_REGNUM) + (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d")) + (const_int 0))) + (set (match_operand:GPR 0 "register_operand" "=d") + (neg:GPR (match_dup 1)))] + "s390_match_ccmode (insn, CCAmode)" + "lc<g>r\t%0,%1" + [(set_attr "op_type" "RR<E>")]) + +; lcr, lcgr +(define_insn "*neg<mode>2_cconly" + [(set (reg CC_REGNUM) + (compare (neg:GPR (match_operand:GPR 1 "register_operand" "d")) + (const_int 0))) + (clobber (match_scratch:GPR 0 "=d"))] + "s390_match_ccmode (insn, CCAmode)" + "lc<g>r\t%0,%1" + [(set_attr "op_type" "RR<E>")]) + +; lcr, lcgr +(define_insn "*neg<mode>2" + [(set (match_operand:GPR 0 "register_operand" "=d") + (neg:GPR (match_operand:GPR 1 "register_operand" "d"))) + (clobber (reg:CC CC_REGNUM))] + "" + "lc<g>r\t%0,%1" + [(set_attr "op_type" "RR<E>")]) + +(define_insn_and_split "*negdi2_31" [(set (match_operand:DI 0 "register_operand" "=d") (neg:DI (match_operand:DI 1 "register_operand" "d"))) - (clobber (reg:CC 33))] + (clobber (reg:CC CC_REGNUM))] "!TARGET_64BIT" -{ - rtx xop[1]; - xop[0] = gen_label_rtx (); - output_asm_insn ("lcr\t%0,%1", operands); - output_asm_insn ("lcr\t%N0,%N1", operands); - output_asm_insn ("je\t%l0", xop); - output_asm_insn ("bctr\t%0,0", operands); - targetm.asm_out.internal_label (asm_out_file, "L", - CODE_LABEL_NUMBER (xop[0])); - return ""; -} - [(set_attr "op_type" "NN") - (set_attr "type" "other") - (set_attr "length" "10")]) - -; -; negsi2 instruction pattern(s). -; - -(define_insn "negsi2" - [(set (match_operand:SI 0 "register_operand" "=d") - (neg:SI (match_operand:SI 1 "register_operand" "d"))) - (clobber (reg:CC 33))] - "" - "lcr\t%0,%1" - [(set_attr "op_type" "RR")]) + "#" + "&& reload_completed" + [(parallel + [(set (match_dup 2) (neg:SI (match_dup 3))) + (clobber (reg:CC CC_REGNUM))]) + (parallel + [(set (reg:CCAP CC_REGNUM) + (compare:CCAP (neg:SI (match_dup 5)) (const_int 0))) + (set (match_dup 4) (neg:SI (match_dup 5)))]) + (set (pc) + (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0)) + (pc) + (label_ref (match_dup 6)))) + (parallel + [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1))) + (clobber (reg:CC CC_REGNUM))]) + (match_dup 6)] + "operands[2] = operand_subword (operands[0], 0, 0, DImode); + operands[3] = operand_subword (operands[1], 0, 0, DImode); + operands[4] = operand_subword (operands[0], 1, 0, DImode); + operands[5] = operand_subword (operands[1], 1, 0, DImode); + operands[6] = gen_label_rtx ();") ; -; negdf2 instruction pattern(s). +; neg(df|sf)2 instruction pattern(s). ; -(define_expand "negdf2" +(define_expand "neg<mode>2" [(parallel - [(set (match_operand:DF 0 "register_operand" "=f") - (neg:DF (match_operand:DF 1 "register_operand" "f"))) - (clobber (reg:CC 33))])] + [(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" "") -(define_insn "*negdf2" - [(set (match_operand:DF 0 "register_operand" "=f") - (neg:DF (match_operand:DF 1 "register_operand" "f"))) - (clobber (reg:CC 33))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "lcdbr\t%0,%1" +; lcxbr, lcdbr, lcebr +(define_insn "*neg<mode>2_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" + "lc<xde>br\t%0,%1" [(set_attr "op_type" "RRE") - (set_attr "type" "fsimpd")]) - -(define_insn "*negdf2_ibm" - [(set (match_operand:DF 0 "register_operand" "=f") - (neg:DF (match_operand:DF 1 "register_operand" "f"))) - (clobber (reg:CC 33))] - "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" - "lcdr\t%0,%1" - [(set_attr "op_type" "RR") - (set_attr "type" "fsimpd")]) - -; -; negsf2 instruction pattern(s). -; - -(define_expand "negsf2" - [(parallel - [(set (match_operand:SF 0 "register_operand" "=f") - (neg:SF (match_operand:SF 1 "register_operand" "f"))) - (clobber (reg:CC 33))])] - "TARGET_HARD_FLOAT" - "") + (set_attr "type" "fsimp<mode>")]) + +; lcxbr, lcdbr, lcebr +(define_insn "*neg<mode>2_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" + "lc<xde>br\t%0,%1" + [(set_attr "op_type" "RRE") + (set_attr "type" "fsimp<mode>")]) -(define_insn "*negsf2" - [(set (match_operand:SF 0 "register_operand" "=f") - (neg:SF (match_operand:SF 1 "register_operand" "f"))) - (clobber (reg:CC 33))] +; lcxbr, lcdbr, lcebr +(define_insn "*neg<mode>2" + [(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" - "lcebr\t%0,%1" + "lc<xde>br\t%0,%1" [(set_attr "op_type" "RRE") - (set_attr "type" "fsimps")]) + (set_attr "type" "fsimp<mode>")]) -(define_insn "*negsf2" - [(set (match_operand:SF 0 "register_operand" "=f") - (neg:SF (match_operand:SF 1 "register_operand" "f"))) - (clobber (reg:CC 33))] +; lcxr, lcdr, lcer +(define_insn "*neg<mode>2_ibm" + [(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_IBM_FLOAT" - "lcer\t%0,%1" - [(set_attr "op_type" "RR") - (set_attr "type" "fsimps")]) + "lc<xde>r\t%0,%1" + [(set_attr "op_type" "<RRe>") + (set_attr "type" "fsimp<mode>")]) ;; @@ -5848,88 +6015,113 @@ ;; ; -; absdi2 instruction pattern(s). +; abs(di|si)2 instruction pattern(s). ; -(define_insn "absdi2" +(define_insn "*absdi2_sign_cc" + [(set (reg CC_REGNUM) + (compare (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI + (match_operand:SI 1 "register_operand" "d") 0) + (const_int 32)) (const_int 32))) + (const_int 0))) + (set (match_operand:DI 0 "register_operand" "=d") + (abs:DI (sign_extend:DI (match_dup 1))))] + "TARGET_64BIT && s390_match_ccmode (insn, CCAmode)" + "lpgfr\t%0,%1" + [(set_attr "op_type" "RRE")]) + +(define_insn "*absdi2_sign" [(set (match_operand:DI 0 "register_operand" "=d") - (abs:DI (match_operand:DI 1 "register_operand" "d"))) - (clobber (reg:CC 33))] + (abs:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d")))) + (clobber (reg:CC CC_REGNUM))] "TARGET_64BIT" - "lpgr\t%0,%1" + "lpgfr\t%0,%1" [(set_attr "op_type" "RRE")]) -; -; abssi2 instruction pattern(s). -; +; lpr, lpgr +(define_insn "*abs<mode>2_cc" + [(set (reg CC_REGNUM) + (compare (abs:GPR (match_operand:DI 1 "register_operand" "d")) + (const_int 0))) + (set (match_operand:GPR 0 "register_operand" "=d") + (abs:GPR (match_dup 1)))] + "s390_match_ccmode (insn, CCAmode)" + "lp<g>r\t%0,%1" + [(set_attr "op_type" "RR<E>")]) + +; lpr, lpgr +(define_insn "*abs<mode>2_cconly" + [(set (reg CC_REGNUM) + (compare (abs:GPR (match_operand:GPR 1 "register_operand" "d")) + (const_int 0))) + (clobber (match_scratch:GPR 0 "=d"))] + "s390_match_ccmode (insn, CCAmode)" + "lp<g>r\t%0,%1" + [(set_attr "op_type" "RR<E>")]) -(define_insn "abssi2" - [(set (match_operand:SI 0 "register_operand" "=d") - (abs:SI (match_operand:SI 1 "register_operand" "d"))) - (clobber (reg:CC 33))] +; lpr, lpgr +(define_insn "abs<mode>2" + [(set (match_operand:GPR 0 "register_operand" "=d") + (abs:GPR (match_operand:GPR 1 "register_operand" "d"))) + (clobber (reg:CC CC_REGNUM))] "" - "lpr\t%0,%1" - [(set_attr "op_type" "RR")]) + "lp<g>r\t%0,%1" + [(set_attr "op_type" "RR<E>")]) ; -; absdf2 instruction pattern(s). +; abs(df|sf)2 instruction pattern(s). ; -(define_expand "absdf2" +(define_expand "abs<mode>2" [(parallel - [(set (match_operand:DF 0 "register_operand" "=f") - (abs:DF (match_operand:DF 1 "register_operand" "f"))) - (clobber (reg:CC 33))])] + [(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" "") -(define_insn "*absdf2" - [(set (match_operand:DF 0 "register_operand" "=f") - (abs:DF (match_operand:DF 1 "register_operand" "f"))) - (clobber (reg:CC 33))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "lpdbr\t%0,%1" +; lpxbr, lpdbr, lpebr +(define_insn "*abs<mode>2_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" + "lp<xde>br\t%0,%1" [(set_attr "op_type" "RRE") - (set_attr "type" "fsimpd")]) - -(define_insn "*absdf2_ibm" - [(set (match_operand:DF 0 "register_operand" "=f") - (abs:DF (match_operand:DF 1 "register_operand" "f"))) - (clobber (reg:CC 33))] - "TARGET_HARD_FLOAT && TARGET_IBM_FLOAT" - "lpdr\t%0,%1" - [(set_attr "op_type" "RR") - (set_attr "type" "fsimpd")]) - -; -; abssf2 instruction pattern(s). -; - -(define_expand "abssf2" - [(parallel - [(set (match_operand:SF 0 "register_operand" "=f") - (abs:SF (match_operand:SF 1 "register_operand" "f"))) - (clobber (reg:CC 33))])] - "TARGET_HARD_FLOAT" - "") + (set_attr "type" "fsimp<mode>")]) + +; lpxbr, lpdbr, lpebr +(define_insn "*abs<mode>2_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" + "lp<xde>br\t%0,%1" + [(set_attr "op_type" "RRE") + (set_attr "type" "fsimp<mode>")]) -(define_insn "*abssf2" - [(set (match_operand:SF 0 "register_operand" "=f") - (abs:SF (match_operand:SF 1 "register_operand" "f"))) - (clobber (reg:CC 33))] +; lpxbr, lpdbr, lpebr +(define_insn "*abs<mode>2" + [(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_IEEE_FLOAT" - "lpebr\t%0,%1" + "lp<xde>br\t%0,%1" [(set_attr "op_type" "RRE") - (set_attr "type" "fsimps")]) + (set_attr "type" "fsimp<mode>")]) -(define_insn "*abssf2_ibm" - [(set (match_operand:SF 0 "register_operand" "=f") - (abs:SF (match_operand:SF 1 "register_operand" "f"))) - (clobber (reg:CC 33))] +; lpxr, lpdr, lper +(define_insn "*abs<mode>2_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" - "lper\t%0,%1" - [(set_attr "op_type" "RR") - (set_attr "type" "fsimps")]) + "lp<xde>r\t%0,%1" + [(set_attr "op_type" "<RRe>") + (set_attr "type" "fsimp<mode>")]) ;; ;;- Negated absolute value instructions @@ -5939,129 +6131,173 @@ ; Integer ; -(define_insn "*negabssi2" - [(set (match_operand:SI 0 "register_operand" "=d") - (neg:SI (abs:SI (match_operand:SI 1 "register_operand" "d")))) - (clobber (reg:CC 33))] - "" - "lnr\t%0,%1" - [(set_attr "op_type" "RR")]) - -(define_insn "*negabsdi2" +(define_insn "*negabsdi2_sign_cc" + [(set (reg CC_REGNUM) + (compare (neg:DI (abs:DI (ashiftrt:DI (ashift:DI (subreg:DI + (match_operand:SI 1 "register_operand" "d") 0) + (const_int 32)) (const_int 32)))) + (const_int 0))) + (set (match_operand:DI 0 "register_operand" "=d") + (neg:DI (abs:DI (sign_extend:DI (match_dup 1)))))] + "TARGET_64BIT && s390_match_ccmode (insn, CCAmode)" + "lngfr\t%0,%1" + [(set_attr "op_type" "RRE")]) + +(define_insn "*negabsdi2_sign" [(set (match_operand:DI 0 "register_operand" "=d") - (neg:DI (abs:DI (match_operand:DI 1 "register_operand" "d")))) - (clobber (reg:CC 33))] + (neg:DI (abs:DI (sign_extend:DI + (match_operand:SI 1 "register_operand" "d"))))) + (clobber (reg:CC CC_REGNUM))] "TARGET_64BIT" - "lngr\t%0,%1" + "lngfr\t%0,%1" [(set_attr "op_type" "RRE")]) +; lnr, lngr +(define_insn "*negabs<mode>2_cc" + [(set (reg CC_REGNUM) + (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d"))) + (const_int 0))) + (set (match_operand:GPR 0 "register_operand" "=d") + (neg:GPR (abs:GPR (match_dup 1))))] + "s390_match_ccmode (insn, CCAmode)" + "ln<g>r\t%0,%1" + [(set_attr "op_type" "RR<E>")]) + +; lnr, lngr +(define_insn "*negabs<mode>2_cconly" + [(set (reg CC_REGNUM) + (compare (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d"))) + (const_int 0))) + (clobber (match_scratch:GPR 0 "=d"))] + "s390_match_ccmode (insn, CCAmode)" + "ln<g>r\t%0,%1" + [(set_attr "op_type" "RR<E>")]) + +; lnr, lngr +(define_insn "*negabs<mode>2" + [(set (match_operand:GPR 0 "register_operand" "=d") + (neg:GPR (abs:GPR (match_operand:GPR 1 "register_operand" "d")))) + (clobber (reg:CC CC_REGNUM))] + "" + "ln<g>r\t%0,%1" + [(set_attr "op_type" "RR<E>")]) + ; ; Floating point ; -(define_insn "*negabssf2" - [(set (match_operand:SF 0 "register_operand" "=f") - (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f")))) - (clobber (reg:CC 33))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "lnebr\t%0,%1" +; lnxbr, lndbr, lnebr +(define_insn "*negabs<mode>2_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" + "ln<xde>br\t%0,%1" + [(set_attr "op_type" "RRE") + (set_attr "type" "fsimp<mode>")]) + +; lnxbr, lndbr, lnebr +(define_insn "*negabs<mode>2_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" + "ln<xde>br\t%0,%1" [(set_attr "op_type" "RRE") - (set_attr "type" "fsimps")]) + (set_attr "type" "fsimp<mode>")]) -(define_insn "*negabsdf2" - [(set (match_operand:DF 0 "register_operand" "=f") - (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f")))) - (clobber (reg:CC 33))] +; lnxbr, lndbr, lnebr +(define_insn "*negabs<mode>2" + [(set (match_operand:FPR 0 "register_operand" "=f") + (neg:FPR (abs:FPR (match_operand:FPR 1 "register_operand" "f")))) + (clobber (reg:CC CC_REGNUM))] "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "lndbr\t%0,%1" + "ln<xde>br\t%0,%1" [(set_attr "op_type" "RRE") - (set_attr "type" "fsimpd")]) + (set_attr "type" "fsimp<mode>")]) ;; ;;- Square root instructions. ;; ; -; sqrtdf2 instruction pattern(s). +; sqrt(df|sf)2 instruction pattern(s). ; -(define_insn "sqrtdf2" - [(set (match_operand:DF 0 "register_operand" "=f,f") - (sqrt:DF (match_operand:DF 1 "general_operand" "f,R")))] +; sqxbr, sqdbr, sqebr, sqxb, sqdb, sqeb +(define_insn "sqrt<mode>2" + [(set (match_operand:FPR 0 "register_operand" "=f,f") + (sqrt:FPR (match_operand:FPR 1 "general_operand" "f,<Rf>")))] "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" "@ - sqdbr\t%0,%1 - sqdb\t%0,%1" - [(set_attr "op_type" "RRE,RXE")]) - -; -; sqrtsf2 instruction pattern(s). -; + sq<xde>br\t%0,%1 + sq<xde>b\t%0,%1" + [(set_attr "op_type" "RRE,RXE") + (set_attr "type" "fsqrt<mode>")]) -(define_insn "sqrtsf2" - [(set (match_operand:SF 0 "register_operand" "=f,f") - (sqrt:SF (match_operand:SF 1 "general_operand" "f,R")))] - "TARGET_HARD_FLOAT && TARGET_IEEE_FLOAT" - "@ - sqebr\t%0,%1 - sqeb\t%0,%1" - [(set_attr "op_type" "RRE,RXE")]) ;; ;;- One complement instructions. ;; ; -; one_cmpldi2 instruction pattern(s). +; one_cmpl(di|si|hi|qi)2 instruction pattern(s). ; -(define_expand "one_cmpldi2" +(define_expand "one_cmpl<mode>2" [(parallel - [(set (match_operand:DI 0 "register_operand" "") - (xor:DI (match_operand:DI 1 "register_operand" "") - (const_int -1))) - (clobber (reg:CC 33))])] - "TARGET_64BIT" + [(set (match_operand:INT 0 "register_operand" "") + (xor:INT (match_operand:INT 1 "register_operand" "") + (const_int -1))) + (clobber (reg:CC CC_REGNUM))])] + "" "") -; -; one_cmplsi2 instruction pattern(s). -; -(define_expand "one_cmplsi2" - [(parallel - [(set (match_operand:SI 0 "register_operand" "") - (xor:SI (match_operand:SI 1 "register_operand" "") - (const_int -1))) - (clobber (reg:CC 33))])] - "" - "") +;; +;; Find leftmost bit instructions. +;; -; -; one_cmplhi2 instruction pattern(s). -; +(define_expand "clzdi2" + [(set (match_operand:DI 0 "register_operand" "=d") + (clz:DI (match_operand:DI 1 "register_operand" "d")))] + "TARGET_EXTIMM && TARGET_64BIT" +{ + rtx insn, clz_equal; + rtx wide_reg = gen_reg_rtx (TImode); + rtx msb = gen_rtx_CONST_INT (DImode, (unsigned HOST_WIDE_INT) 1 << 63); -(define_expand "one_cmplhi2" - [(parallel - [(set (match_operand:HI 0 "register_operand" "") - (xor:HI (match_operand:HI 1 "register_operand" "") - (const_int -1))) - (clobber (reg:CC 33))])] - "" - "") + clz_equal = gen_rtx_CLZ (DImode, operands[1]); -; -; one_cmplqi2 instruction pattern(s). -; + emit_insn (gen_clztidi2 (wide_reg, operands[1], msb)); -(define_expand "one_cmplqi2" - [(parallel - [(set (match_operand:QI 0 "register_operand" "") - (xor:QI (match_operand:QI 1 "register_operand" "") - (const_int -1))) - (clobber (reg:CC 33))])] - "" - "") + 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)); + + DONE; +}) + +(define_insn "clztidi2" + [(set (match_operand:TI 0 "register_operand" "=d") + (ior:TI + (ashift:TI + (zero_extend:TI + (xor:DI (match_operand:DI 1 "register_operand" "d") + (lshiftrt (match_operand:DI 2 "const_int_operand" "") + (subreg:SI (clz:DI (match_dup 1)) 4)))) + + (const_int 64)) + (zero_extend:TI (clz:DI (match_dup 1))))) + (clobber (reg:CC CC_REGNUM))] + "(unsigned HOST_WIDE_INT) INTVAL (operands[2]) + == (unsigned HOST_WIDE_INT) 1 << 63 + && TARGET_EXTIMM && TARGET_64BIT" + "flogr\t%0,%1" + [(set_attr "op_type" "RRE")]) ;; @@ -6069,82 +6305,105 @@ ;; ; -; rotldi3 instruction pattern(s). +; rotl(di|si)3 instruction pattern(s). ; -(define_insn "rotldi3" - [(set (match_operand:DI 0 "register_operand" "=d") - (rotate:DI (match_operand:DI 1 "register_operand" "d") - (match_operand:SI 2 "shift_count_operand" "Y")))] - "TARGET_64BIT" - "rllg\t%0,%1,%Y2" +; rll, rllg +(define_insn "rotl<mode>3" + [(set (match_operand:GPR 0 "register_operand" "=d") + (rotate:GPR (match_operand:GPR 1 "register_operand" "d") + (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))] + "TARGET_CPU_ZARCH" + "rll<g>\t%0,%1,%Y2" [(set_attr "op_type" "RSE") (set_attr "atype" "reg")]) -; -; rotlsi3 instruction pattern(s). -; - -(define_insn "rotlsi3" - [(set (match_operand:SI 0 "register_operand" "=d") - (rotate:SI (match_operand:SI 1 "register_operand" "d") - (match_operand:SI 2 "shift_count_operand" "Y")))] - "TARGET_CPU_ZARCH" - "rll\t%0,%1,%Y2" +; rll, rllg +(define_insn "*rotl<mode>3_and" + [(set (match_operand:GPR 0 "register_operand" "=d") + (rotate:GPR (match_operand:GPR 1 "register_operand" "d") + (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y") + (match_operand:SI 3 "const_int_operand" "n"))))] + "TARGET_CPU_ZARCH && (INTVAL (operands[3]) & 63) == 63" + "rll<g>\t%0,%1,%Y2" [(set_attr "op_type" "RSE") (set_attr "atype" "reg")]) ;; -;;- Arithmetic shift instructions. +;;- Shift instructions. ;; ; -; ashldi3 instruction pattern(s). +; (ashl|lshr)(di|si)3 instruction pattern(s). ; -(define_expand "ashldi3" - [(set (match_operand:DI 0 "register_operand" "") - (ashift:DI (match_operand:DI 1 "register_operand" "") - (match_operand:SI 2 "shift_count_operand" "")))] +(define_expand "<shift><mode>3" + [(set (match_operand:DSI 0 "register_operand" "") + (SHIFT:DSI (match_operand:DSI 1 "register_operand" "") + (match_operand:SI 2 "shift_count_or_setmem_operand" "")))] "" "") -(define_insn "*ashldi3_31" +; sldl, srdl +(define_insn "*<shift>di3_31" [(set (match_operand:DI 0 "register_operand" "=d") - (ashift:DI (match_operand:DI 1 "register_operand" "0") - (match_operand:SI 2 "shift_count_operand" "Y")))] + (SHIFT:DI (match_operand:DI 1 "register_operand" "0") + (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))] "!TARGET_64BIT" - "sldl\t%0,%Y2" + "s<lr>dl\t%0,%Y2" [(set_attr "op_type" "RS") (set_attr "atype" "reg")]) -(define_insn "*ashldi3_64" +; sll, srl, sllg, srlg +(define_insn "*<shift><mode>3" + [(set (match_operand:GPR 0 "register_operand" "=d") + (SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>") + (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))] + "" + "s<lr>l<g>\t%0,<1>%Y2" + [(set_attr "op_type" "RS<E>") + (set_attr "atype" "reg")]) + +; sldl, srdl +(define_insn "*<shift>di3_31_and" [(set (match_operand:DI 0 "register_operand" "=d") - (ashift:DI (match_operand:DI 1 "register_operand" "d") - (match_operand:SI 2 "shift_count_operand" "Y")))] - "TARGET_64BIT" - "sllg\t%0,%1,%Y2" - [(set_attr "op_type" "RSE") + (SHIFT:DI (match_operand:DI 1 "register_operand" "0") + (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y") + (match_operand:SI 3 "const_int_operand" "n"))))] + "!TARGET_64BIT && (INTVAL (operands[3]) & 63) == 63" + "s<lr>dl\t%0,%Y2" + [(set_attr "op_type" "RS") + (set_attr "atype" "reg")]) + +; sll, srl, sllg, srlg +(define_insn "*<shift><mode>3_and" + [(set (match_operand:GPR 0 "register_operand" "=d") + (SHIFT:GPR (match_operand:GPR 1 "register_operand" "<d0>") + (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y") + (match_operand:SI 3 "const_int_operand" "n"))))] + "(INTVAL (operands[3]) & 63) == 63" + "s<lr>l<g>\t%0,<1>%Y2" + [(set_attr "op_type" "RS<E>") (set_attr "atype" "reg")]) ; -; ashrdi3 instruction pattern(s). +; ashr(di|si)3 instruction pattern(s). ; -(define_expand "ashrdi3" +(define_expand "ashr<mode>3" [(parallel - [(set (match_operand:DI 0 "register_operand" "") - (ashiftrt:DI (match_operand:DI 1 "register_operand" "") - (match_operand:SI 2 "shift_count_operand" ""))) - (clobber (reg:CC 33))])] + [(set (match_operand:DSI 0 "register_operand" "") + (ashiftrt:DSI (match_operand:DSI 1 "register_operand" "") + (match_operand:SI 2 "shift_count_or_setmem_operand" ""))) + (clobber (reg:CC CC_REGNUM))])] "" "") (define_insn "*ashrdi3_cc_31" - [(set (reg 33) + [(set (reg CC_REGNUM) (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") - (match_operand:SI 2 "shift_count_operand" "Y")) + (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")) (const_int 0))) (set (match_operand:DI 0 "register_operand" "=d") (ashiftrt:DI (match_dup 1) (match_dup 2)))] @@ -6154,9 +6413,9 @@ (set_attr "atype" "reg")]) (define_insn "*ashrdi3_cconly_31" - [(set (reg 33) + [(set (reg CC_REGNUM) (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") - (match_operand:SI 2 "shift_count_operand" "Y")) + (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")) (const_int 0))) (clobber (match_scratch:DI 0 "=d"))] "!TARGET_64BIT && s390_match_ccmode(insn, CCSmode)" @@ -6167,143 +6426,127 @@ (define_insn "*ashrdi3_31" [(set (match_operand:DI 0 "register_operand" "=d") (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") - (match_operand:SI 2 "shift_count_operand" "Y"))) - (clobber (reg:CC 33))] + (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))) + (clobber (reg:CC CC_REGNUM))] "!TARGET_64BIT" "srda\t%0,%Y2" [(set_attr "op_type" "RS") (set_attr "atype" "reg")]) -(define_insn "*ashrdi3_cc_64" - [(set (reg 33) - (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "d") - (match_operand:SI 2 "shift_count_operand" "Y")) +; sra, srag +(define_insn "*ashr<mode>3_cc" + [(set (reg CC_REGNUM) + (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>") + (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")) (const_int 0))) - (set (match_operand:DI 0 "register_operand" "=d") - (ashiftrt:DI (match_dup 1) (match_dup 2)))] - "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT" - "srag\t%0,%1,%Y2" - [(set_attr "op_type" "RSE") + (set (match_operand:GPR 0 "register_operand" "=d") + (ashiftrt:GPR (match_dup 1) (match_dup 2)))] + "s390_match_ccmode(insn, CCSmode)" + "sra<g>\t%0,<1>%Y2" + [(set_attr "op_type" "RS<E>") (set_attr "atype" "reg")]) -(define_insn "*ashrdi3_cconly_64" - [(set (reg 33) - (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "d") - (match_operand:SI 2 "shift_count_operand" "Y")) +; sra, srag +(define_insn "*ashr<mode>3_cconly" + [(set (reg CC_REGNUM) + (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>") + (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")) (const_int 0))) - (clobber (match_scratch:DI 0 "=d"))] - "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT" - "srag\t%0,%1,%Y2" - [(set_attr "op_type" "RSE") + (clobber (match_scratch:GPR 0 "=d"))] + "s390_match_ccmode(insn, CCSmode)" + "sra<g>\t%0,<1>%Y2" + [(set_attr "op_type" "RS<E>") (set_attr "atype" "reg")]) -(define_insn "*ashrdi3_64" - [(set (match_operand:DI 0 "register_operand" "=d") - (ashiftrt:DI (match_operand:DI 1 "register_operand" "d") - (match_operand:SI 2 "shift_count_operand" "Y"))) - (clobber (reg:CC 33))] - "TARGET_64BIT" - "srag\t%0,%1,%Y2" - [(set_attr "op_type" "RSE") +; sra, srag +(define_insn "*ashr<mode>3" + [(set (match_operand:GPR 0 "register_operand" "=d") + (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>") + (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))) + (clobber (reg:CC CC_REGNUM))] + "" + "sra<g>\t%0,<1>%Y2" + [(set_attr "op_type" "RS<E>") (set_attr "atype" "reg")]) -; -; ashlsi3 instruction pattern(s). -; +; shift pattern with implicit ANDs -(define_insn "ashlsi3" - [(set (match_operand:SI 0 "register_operand" "=d") - (ashift:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "shift_count_operand" "Y")))] - "" - "sll\t%0,%Y2" +(define_insn "*ashrdi3_cc_31_and" + [(set (reg CC_REGNUM) + (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") + (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y") + (match_operand:SI 3 "const_int_operand" "n"))) + (const_int 0))) + (set (match_operand:DI 0 "register_operand" "=d") + (ashiftrt:DI (match_dup 1) (and:SI (match_dup 2) (match_dup 3))))] + "!TARGET_64BIT && s390_match_ccmode(insn, CCSmode) + && (INTVAL (operands[3]) & 63) == 63" + "srda\t%0,%Y2" [(set_attr "op_type" "RS") (set_attr "atype" "reg")]) -; -; ashrsi3 instruction pattern(s). -; - -(define_insn "*ashrsi3_cc" - [(set (reg 33) - (compare (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "shift_count_operand" "Y")) +(define_insn "*ashrdi3_cconly_31_and" + [(set (reg CC_REGNUM) + (compare (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") + (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y") + (match_operand:SI 3 "const_int_operand" "n"))) (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=d") - (ashiftrt:SI (match_dup 1) (match_dup 2)))] - "s390_match_ccmode(insn, CCSmode)" - "sra\t%0,%Y2" + (clobber (match_scratch:DI 0 "=d"))] + "!TARGET_64BIT && s390_match_ccmode(insn, CCSmode) + && (INTVAL (operands[3]) & 63) == 63" + "srda\t%0,%Y2" [(set_attr "op_type" "RS") (set_attr "atype" "reg")]) - -(define_insn "*ashrsi3_cconly" - [(set (reg 33) - (compare (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "shift_count_operand" "Y")) - (const_int 0))) - (clobber (match_scratch:SI 0 "=d"))] - "s390_match_ccmode(insn, CCSmode)" - "sra\t%0,%Y2" +(define_insn "*ashrdi3_31_and" + [(set (match_operand:DI 0 "register_operand" "=d") + (ashiftrt:DI (match_operand:DI 1 "register_operand" "0") + (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y") + (match_operand:SI 3 "const_int_operand" "n")))) + (clobber (reg:CC CC_REGNUM))] + "!TARGET_64BIT && (INTVAL (operands[3]) & 63) == 63" + "srda\t%0,%Y2" [(set_attr "op_type" "RS") (set_attr "atype" "reg")]) -(define_insn "ashrsi3" - [(set (match_operand:SI 0 "register_operand" "=d") - (ashiftrt:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "shift_count_operand" "Y"))) - (clobber (reg:CC 33))] - "" - "sra\t%0,%Y2" - [(set_attr "op_type" "RS") +; sra, srag +(define_insn "*ashr<mode>3_cc_and" + [(set (reg CC_REGNUM) + (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>") + (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y") + (match_operand:SI 3 "const_int_operand" "n"))) + (const_int 0))) + (set (match_operand:GPR 0 "register_operand" "=d") + (ashiftrt:GPR (match_dup 1) (and:SI (match_dup 2) (match_dup 3))))] + "s390_match_ccmode(insn, CCSmode) && (INTVAL (operands[3]) & 63) == 63" + "sra<g>\t%0,<1>%Y2" + [(set_attr "op_type" "RS<E>") (set_attr "atype" "reg")]) - -;; -;;- logical shift instructions. -;; - -; -; lshrdi3 instruction pattern(s). -; - -(define_expand "lshrdi3" - [(set (match_operand:DI 0 "register_operand" "") - (lshiftrt:DI (match_operand:DI 1 "register_operand" "") - (match_operand:SI 2 "shift_count_operand" "")))] - "" - "") - -(define_insn "*lshrdi3_31" - [(set (match_operand:DI 0 "register_operand" "=d") - (lshiftrt:DI (match_operand:DI 1 "register_operand" "0") - (match_operand:SI 2 "shift_count_operand" "Y")))] - "!TARGET_64BIT" - "srdl\t%0,%Y2" - [(set_attr "op_type" "RS") - (set_attr "atype" "reg")]) - -(define_insn "*lshrdi3_64" - [(set (match_operand:DI 0 "register_operand" "=d") - (lshiftrt:DI (match_operand:DI 1 "register_operand" "d") - (match_operand:SI 2 "shift_count_operand" "Y")))] - "TARGET_64BIT" - "srlg\t%0,%1,%Y2" - [(set_attr "op_type" "RSE") +; sra, srag +(define_insn "*ashr<mode>3_cconly_and" + [(set (reg CC_REGNUM) + (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>") + (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y") + (match_operand:SI 3 "const_int_operand" "n"))) + (const_int 0))) + (clobber (match_scratch:GPR 0 "=d"))] + "s390_match_ccmode(insn, CCSmode) && (INTVAL (operands[3]) & 63) == 63" + "sra<g>\t%0,<1>%Y2" + [(set_attr "op_type" "RS<E>") (set_attr "atype" "reg")]) -; -; lshrsi3 instruction pattern(s). -; - -(define_insn "lshrsi3" - [(set (match_operand:SI 0 "register_operand" "=d") - (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:SI 2 "shift_count_operand" "Y")))] - "" - "srl\t%0,%Y2" - [(set_attr "op_type" "RS") +; sra, srag +(define_insn "*ashr<mode>3_and" + [(set (match_operand:GPR 0 "register_operand" "=d") + (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "<d0>") + (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y") + (match_operand:SI 3 "const_int_operand" "n")))) + (clobber (reg:CC CC_REGNUM))] + "(INTVAL (operands[3]) & 63) == 63" + "sra<g>\t%0,<1>%Y2" + [(set_attr "op_type" "RS<E>") (set_attr "atype" "reg")]) @@ -6311,204 +6554,66 @@ ;; Branch instruction patterns. ;; -(define_expand "beq" - [(set (reg:CCZ 33) (compare:CCZ (match_dup 1) (match_dup 2))) - (set (pc) - (if_then_else (eq (reg:CCZ 33) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;") - -(define_expand "bne" - [(set (reg:CCZ 33) (compare:CCZ (match_dup 1) (match_dup 2))) - (set (pc) - (if_then_else (ne (reg:CCZ 33) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;") - -(define_expand "bgt" - [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2))) - (set (pc) - (if_then_else (gt (reg:CCS 33) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;") - -(define_expand "bgtu" - [(set (reg:CCU 33) (compare:CCU (match_dup 1) (match_dup 2))) - (set (pc) - (if_then_else (gtu (reg:CCU 33) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;") - -(define_expand "blt" - [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2))) - (set (pc) - (if_then_else (lt (reg:CCS 33) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;") - -(define_expand "bltu" - [(set (reg:CCU 33) (compare:CCU (match_dup 1) (match_dup 2))) - (set (pc) - (if_then_else (ltu (reg:CCU 33) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;") - -(define_expand "bge" - [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2))) - (set (pc) - (if_then_else (ge (reg:CCS 33) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;") - -(define_expand "bgeu" - [(set (reg:CCU 33) (compare:CCU (match_dup 1) (match_dup 2))) - (set (pc) - (if_then_else (geu (reg:CCU 33) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;") - -(define_expand "ble" - [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2))) - (set (pc) - (if_then_else (le (reg:CCS 33) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;") - -(define_expand "bleu" - [(set (reg:CCU 33) (compare:CCU (match_dup 1) (match_dup 2))) - (set (pc) - (if_then_else (leu (reg:CCU 33) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;") - -(define_expand "bunordered" - [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2))) - (set (pc) - (if_then_else (unordered (reg:CCS 33) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;") - -(define_expand "bordered" - [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2))) - (set (pc) - (if_then_else (ordered (reg:CCS 33) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;") - -(define_expand "buneq" - [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2))) - (set (pc) - (if_then_else (uneq (reg:CCS 33) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;") - -(define_expand "bungt" - [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2))) - (set (pc) - (if_then_else (ungt (reg:CCS 33) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;") - -(define_expand "bunlt" - [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2))) - (set (pc) - (if_then_else (unlt (reg:CCS 33) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;") - -(define_expand "bunge" - [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2))) - (set (pc) - (if_then_else (unge (reg:CCS 33) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;") - -(define_expand "bunle" - [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2))) - (set (pc) - (if_then_else (unle (reg:CCS 33) (const_int 0)) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" - "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;") - -(define_expand "bltgt" - [(set (reg:CCS 33) (compare:CCS (match_dup 1) (match_dup 2))) - (set (pc) - (if_then_else (ltgt (reg:CCS 33) (const_int 0)) - (label_ref (match_operand 0 "" "")) +(define_expand "b<code>" + [(set (pc) + (if_then_else (COMPARE (match_operand 0 "" "") + (const_int 0)) + (match_dup 0) (pc)))] "" - "operands[1] = s390_compare_op0; operands[2] = s390_compare_op1;") + "s390_emit_jump (operands[0], + s390_emit_compare (<CODE>, s390_compare_op0, s390_compare_op1)); DONE;") ;; ;;- Conditional jump instructions. ;; -(define_insn "cjump" - [(set (pc) - (if_then_else - (match_operator 1 "comparison_operator" [(reg 33) (const_int 0)]) - (label_ref (match_operand 0 "" "")) - (pc)))] - "" +(define_insn "*cjump_64" + [(set (pc) + (if_then_else + (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)]) + (label_ref (match_operand 0 "" "")) + (pc)))] + "TARGET_CPU_ZARCH" { if (get_attr_length (insn) == 4) return "j%C1\t%l0"; - else if (TARGET_CPU_ZARCH) - return "jg%C1\t%l0"; else - abort (); + return "jg%C1\t%l0"; +} + [(set_attr "op_type" "RI") + (set_attr "type" "branch") + (set (attr "length") + (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) + (const_int 4) (const_int 6)))]) + +(define_insn "*cjump_31" + [(set (pc) + (if_then_else + (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)]) + (label_ref (match_operand 0 "" "")) + (pc)))] + "!TARGET_CPU_ZARCH" +{ + gcc_assert (get_attr_length (insn) == 4); + return "j%C1\t%l0"; } [(set_attr "op_type" "RI") (set_attr "type" "branch") (set (attr "length") - (cond [(lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) - (const_int 4) - (ne (symbol_ref "TARGET_CPU_ZARCH") (const_int 0)) - (const_int 6) - (eq (symbol_ref "flag_pic") (const_int 0)) - (const_int 6)] (const_int 8)))]) + (if_then_else (eq (symbol_ref "flag_pic") (const_int 0)) + (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) + (const_int 4) (const_int 6)) + (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) + (const_int 4) (const_int 8))))]) (define_insn "*cjump_long" - [(set (pc) - (if_then_else - (match_operator 1 "comparison_operator" [(reg 33) (const_int 0)]) - (match_operand 0 "address_operand" "U") - (pc)))] + [(set (pc) + (if_then_else + (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)]) + (match_operand 0 "address_operand" "U") + (pc)))] "" { if (get_attr_op_type (insn) == OP_TYPE_RR) @@ -6519,7 +6624,7 @@ [(set (attr "op_type") (if_then_else (match_operand 0 "register_operand" "") (const_string "RR") (const_string "RX"))) - (set_attr "type" "branch") + (set_attr "type" "branch") (set_attr "atype" "agen")]) @@ -6527,37 +6632,51 @@ ;;- Negated conditional jump instructions. ;; -(define_insn "icjump" - [(set (pc) - (if_then_else - (match_operator 1 "comparison_operator" [(reg 33) (const_int 0)]) - (pc) - (label_ref (match_operand 0 "" ""))))] - "" +(define_insn "*icjump_64" + [(set (pc) + (if_then_else + (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)]) + (pc) + (label_ref (match_operand 0 "" ""))))] + "TARGET_CPU_ZARCH" { if (get_attr_length (insn) == 4) return "j%D1\t%l0"; - else if (TARGET_CPU_ZARCH) - return "jg%D1\t%l0"; else - abort (); + return "jg%D1\t%l0"; +} + [(set_attr "op_type" "RI") + (set_attr "type" "branch") + (set (attr "length") + (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) + (const_int 4) (const_int 6)))]) + +(define_insn "*icjump_31" + [(set (pc) + (if_then_else + (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)]) + (pc) + (label_ref (match_operand 0 "" ""))))] + "!TARGET_CPU_ZARCH" +{ + gcc_assert (get_attr_length (insn) == 4); + return "j%D1\t%l0"; } [(set_attr "op_type" "RI") (set_attr "type" "branch") (set (attr "length") - (cond [(lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) - (const_int 4) - (ne (symbol_ref "TARGET_CPU_ZARCH") (const_int 0)) - (const_int 6) - (eq (symbol_ref "flag_pic") (const_int 0)) - (const_int 6)] (const_int 8)))]) + (if_then_else (eq (symbol_ref "flag_pic") (const_int 0)) + (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) + (const_int 4) (const_int 6)) + (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) + (const_int 4) (const_int 8))))]) (define_insn "*icjump_long" - [(set (pc) - (if_then_else - (match_operator 1 "comparison_operator" [(reg 33) (const_int 0)]) - (pc) - (match_operand 0 "address_operand" "U")))] + [(set (pc) + (if_then_else + (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)]) + (pc) + (match_operand 0 "address_operand" "U")))] "" { if (get_attr_op_type (insn) == OP_TYPE_RR) @@ -6579,28 +6698,21 @@ [(trap_if (const_int 1) (const_int 0))] "" "j\t.+2" - [(set_attr "op_type" "RX") + [(set_attr "op_type" "RI") (set_attr "type" "branch")]) (define_expand "conditional_trap" - [(set (match_dup 2) (match_dup 3)) - (trap_if (match_operator 0 "comparison_operator" - [(match_dup 2) (const_int 0)]) - (match_operand:SI 1 "general_operand" ""))] + [(trap_if (match_operand 0 "comparison_operator" "") + (match_operand 1 "general_operand" ""))] "" { - enum machine_mode ccmode; - - if (operands[1] != const0_rtx) FAIL; - - ccmode = s390_select_ccmode (GET_CODE (operands[0]), - s390_compare_op0, s390_compare_op1); - operands[2] = gen_rtx_REG (ccmode, 33); - operands[3] = gen_rtx_COMPARE (ccmode, s390_compare_op0, s390_compare_op1); + if (operands[1] != const0_rtx) FAIL; + operands[0] = s390_emit_compare (GET_CODE (operands[0]), + s390_compare_op0, s390_compare_op1); }) (define_insn "*trap" - [(trap_if (match_operator 0 "comparison_operator" [(reg 33) (const_int 0)]) + [(trap_if (match_operator 0 "s390_comparison" [(reg CC_REGNUM) (const_int 0)]) (const_int 0))] "" "j%C0\t.+2"; @@ -6621,8 +6733,10 @@ (use (match_operand 4 "" ""))] ; label "" { - if (GET_MODE (operands[0]) == SImode) - emit_jump_insn (gen_doloop_si (operands[4], operands[0], operands[0])); + if (GET_MODE (operands[0]) == SImode && !TARGET_CPU_ZARCH) + emit_jump_insn (gen_doloop_si31 (operands[4], operands[0], operands[0])); + else if (GET_MODE (operands[0]) == SImode && TARGET_CPU_ZARCH) + emit_jump_insn (gen_doloop_si64 (operands[4], operands[0], operands[0])); else if (GET_MODE (operands[0]) == DImode && TARGET_64BIT) emit_jump_insn (gen_doloop_di (operands[4], operands[0], operands[0])); else @@ -6631,50 +6745,99 @@ DONE; }) -(define_insn "doloop_si" +(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 "register_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,&d")) - (clobber (reg:CC 33))] - "" + (clobber (match_scratch:SI 3 "=X,&1,&?d")) + (clobber (reg:CC CC_REGNUM))] + "TARGET_CPU_ZARCH" { if (which_alternative != 0) return "#"; else if (get_attr_length (insn) == 4) return "brct\t%1,%l0"; - else if (TARGET_CPU_ZARCH) + else return "ahi\t%1,-1\;jgne\t%l0"; +} + "&& reload_completed + && (! REG_P (operands[2]) + || ! rtx_equal_p (operands[1], operands[2]))" + [(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)))]) + (set (match_dup 2) (match_dup 3)) + (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0)) + (label_ref (match_dup 0)) + (pc)))] + "" + [(set_attr "op_type" "RI") + (set_attr "type" "branch") + (set (attr "length") + (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) + (const_int 4) (const_int 10)))]) + +(define_insn_and_split "doloop_si31" + [(set (pc) + (if_then_else + (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,?X,?X") + (plus:SI (match_dup 1) (const_int -1))) + (clobber (match_scratch:SI 3 "=X,&1,&?d")) + (clobber (reg:CC CC_REGNUM))] + "!TARGET_CPU_ZARCH" +{ + if (which_alternative != 0) + return "#"; + else if (get_attr_length (insn) == 4) + return "brct\t%1,%l0"; else - abort (); + gcc_unreachable (); } + "&& reload_completed + && (! REG_P (operands[2]) + || ! rtx_equal_p (operands[1], operands[2]))" + [(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)))]) + (set (match_dup 2) (match_dup 3)) + (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0)) + (label_ref (match_dup 0)) + (pc)))] + "" [(set_attr "op_type" "RI") (set_attr "type" "branch") (set (attr "length") - (cond [(lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) - (const_int 4) - (ne (symbol_ref "TARGET_CPU_ZARCH") (const_int 0)) - (const_int 10) - (eq (symbol_ref "flag_pic") (const_int 0)) - (const_int 6)] (const_int 8)))]) + (if_then_else (eq (symbol_ref "flag_pic") (const_int 0)) + (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) + (const_int 4) (const_int 6)) + (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) + (const_int 4) (const_int 8))))]) (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,&d")) - (clobber (reg:CC 33))] - "" + (clobber (match_scratch:SI 3 "=X")) + (clobber (reg:CC CC_REGNUM))] + "!TARGET_CPU_ZARCH" { if (get_attr_op_type (insn) == OP_TYPE_RR) return "bctr\t%1,%0"; @@ -6687,41 +6850,17 @@ (set_attr "type" "branch") (set_attr "atype" "agen")]) -(define_split - [(set (pc) - (if_then_else (ne (match_operand:SI 1 "register_operand" "") - (const_int 1)) - (match_operand 0 "" "") - (pc))) - (set (match_operand:SI 2 "nonimmediate_operand" "") - (plus:SI (match_dup 1) (const_int -1))) - (clobber (match_scratch:SI 3 "")) - (clobber (reg:CC 33))] - "reload_completed - && (! REG_P (operands[2]) - || ! rtx_equal_p (operands[1], operands[2]))" - [(set (match_dup 3) (match_dup 1)) - (parallel [(set (reg:CCAN 33) - (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)))]) - (set (match_dup 2) (match_dup 3)) - (set (pc) (if_then_else (ne (reg:CCAN 33) (const_int 0)) - (match_dup 0) - (pc)))] - "") - -(define_insn "doloop_di" +(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 "register_operand" "=1,?*m*r") + (set (match_operand:DI 2 "nonimmediate_operand" "=1,?X,?X") (plus:DI (match_dup 1) (const_int -1))) - (clobber (match_scratch:DI 3 "=X,&d")) - (clobber (reg:CC 33))] + (clobber (match_scratch:DI 3 "=X,&1,&?d")) + (clobber (reg:CC CC_REGNUM))] "TARGET_64BIT" { if (which_alternative != 0) @@ -6731,35 +6870,24 @@ else return "aghi\t%1,-1\;jgne\t%l0"; } - [(set_attr "op_type" "RI") - (set_attr "type" "branch") - (set (attr "length") - (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) - (const_int 4) (const_int 10)))]) - -(define_split - [(set (pc) - (if_then_else (ne (match_operand:DI 1 "register_operand" "") - (const_int 1)) - (match_operand 0 "" "") - (pc))) - (set (match_operand:DI 2 "nonimmediate_operand" "") - (plus:DI (match_dup 1) (const_int -1))) - (clobber (match_scratch:DI 3 "")) - (clobber (reg:CC 33))] - "reload_completed + "&& reload_completed && (! REG_P (operands[2]) || ! rtx_equal_p (operands[1], operands[2]))" [(set (match_dup 3) (match_dup 1)) - (parallel [(set (reg:CCAN 33) + (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)))]) (set (match_dup 2) (match_dup 3)) - (set (pc) (if_then_else (ne (reg:CCAN 33) (const_int 0)) - (match_dup 0) + (set (pc) (if_then_else (ne (reg:CCAN CC_REGNUM) (const_int 0)) + (label_ref (match_dup 0)) (pc)))] - "") + "" + [(set_attr "op_type" "RI") + (set_attr "type" "branch") + (set (attr "length") + (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) + (const_int 4) (const_int 10)))]) ;; ;;- Unconditional jump instructions. @@ -6769,26 +6897,41 @@ ; jump instruction pattern(s). ; -(define_insn "jump" - [(set (pc) (label_ref (match_operand 0 "" "")))] +(define_expand "jump" + [(match_operand 0 "" "")] "" + "s390_emit_jump (operands[0], NULL_RTX); DONE;") + +(define_insn "*jump64" + [(set (pc) (label_ref (match_operand 0 "" "")))] + "TARGET_CPU_ZARCH" { if (get_attr_length (insn) == 4) return "j\t%l0"; - else if (TARGET_CPU_ZARCH) - return "jg\t%l0"; else - abort (); + return "jg\t%l0"; } [(set_attr "op_type" "RI") (set_attr "type" "branch") (set (attr "length") - (cond [(lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) - (const_int 4) - (ne (symbol_ref "TARGET_CPU_ZARCH") (const_int 0)) - (const_int 6) - (eq (symbol_ref "flag_pic") (const_int 0)) - (const_int 6)] (const_int 8)))]) + (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) + (const_int 4) (const_int 6)))]) + +(define_insn "*jump31" + [(set (pc) (label_ref (match_operand 0 "" "")))] + "!TARGET_CPU_ZARCH" +{ + gcc_assert (get_attr_length (insn) == 4); + return "j\t%l0"; +} + [(set_attr "op_type" "RI") + (set_attr "type" "branch") + (set (attr "length") + (if_then_else (eq (symbol_ref "flag_pic") (const_int 0)) + (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) + (const_int 4) (const_int 6)) + (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) + (const_int 4) (const_int 8))))]) ; ; indirect-jump instruction pattern(s). @@ -6854,11 +6997,11 @@ if (TARGET_64BIT) emit_insn (gen_ashldi3 (index, index, GEN_INT (3))); else - emit_insn (gen_ashlsi3 (index, index, GEN_INT (2))); + emit_insn (gen_ashlsi3 (index, index, const2_rtx)); emit_move_insn (base, gen_rtx_LABEL_REF (Pmode, operands[3])); - index = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, base, index)); + index = gen_const_mem (Pmode, gen_rtx_PLUS (Pmode, base, index)); emit_move_insn (target, index); if (flag_pic) @@ -6915,71 +7058,111 @@ [(set_attr "type" "none") (set_attr "length" "0")]) - - ; -; call instruction pattern(s). +; sibcall patterns ; -(define_expand "call" +(define_expand "sibcall" [(call (match_operand 0 "" "") - (match_operand 1 "" "")) - (use (match_operand 2 "" ""))] + (match_operand 1 "" ""))] "" { - bool plt_call = false; - rtx insn; - - /* Direct function calls need special treatment. */ - if (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF) - { - rtx sym = XEXP (operands[0], 0); + s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX, NULL_RTX); + DONE; +}) - /* When calling a global routine in PIC mode, we must - replace the symbol itself with the PLT stub. */ - if (flag_pic && !SYMBOL_REF_LOCAL_P (sym)) - { - sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), UNSPEC_PLT); - sym = gen_rtx_CONST (Pmode, sym); - plt_call = true; - } +(define_insn "*sibcall_br" + [(call (mem:QI (reg SIBCALL_REGNUM)) + (match_operand 0 "const_int_operand" "n"))] + "SIBLING_CALL_P (insn) + && GET_MODE (XEXP (XEXP (PATTERN (insn), 0), 0)) == Pmode" + "br\t%%r1" + [(set_attr "op_type" "RR") + (set_attr "type" "branch") + (set_attr "atype" "agen")]) - /* Unless we can use the bras(l) insn, force the - routine address into a register. */ - if (!TARGET_SMALL_EXEC && !TARGET_CPU_ZARCH) - { - if (flag_pic) - sym = legitimize_pic_address (sym, 0); - else - sym = force_reg (Pmode, sym); - } +(define_insn "*sibcall_brc" + [(call (mem:QI (match_operand 0 "bras_sym_operand" "X")) + (match_operand 1 "const_int_operand" "n"))] + "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC" + "j\t%0" + [(set_attr "op_type" "RI") + (set_attr "type" "branch")]) - operands[0] = gen_rtx_MEM (QImode, sym); - } +(define_insn "*sibcall_brcl" + [(call (mem:QI (match_operand 0 "bras_sym_operand" "X")) + (match_operand 1 "const_int_operand" "n"))] + "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH" + "jg\t%0" + [(set_attr "op_type" "RIL") + (set_attr "type" "branch")]) - /* Emit insn. */ - insn = emit_call_insn (gen_call_exp (operands[0], operands[1], - gen_rtx_REG (Pmode, RETURN_REGNUM))); +; +; sibcall_value patterns +; - /* 31-bit PLT stubs use the GOT register implicitly. */ - if (!TARGET_64BIT && plt_call) - use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx); - +(define_expand "sibcall_value" + [(set (match_operand 0 "" "") + (call (match_operand 1 "" "") + (match_operand 2 "" "")))] + "" +{ + s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0], NULL_RTX); DONE; }) -(define_expand "call_exp" - [(parallel [(call (match_operand 0 "" "") - (match_operand 1 "" "")) - (clobber (match_operand 2 "" ""))])] +(define_insn "*sibcall_value_br" + [(set (match_operand 0 "" "") + (call (mem:QI (reg SIBCALL_REGNUM)) + (match_operand 1 "const_int_operand" "n")))] + "SIBLING_CALL_P (insn) + && GET_MODE (XEXP (XEXP (XEXP (PATTERN (insn), 1), 0), 0)) == Pmode" + "br\t%%r1" + [(set_attr "op_type" "RR") + (set_attr "type" "branch") + (set_attr "atype" "agen")]) + +(define_insn "*sibcall_value_brc" + [(set (match_operand 0 "" "") + (call (mem:QI (match_operand 1 "bras_sym_operand" "X")) + (match_operand 2 "const_int_operand" "n")))] + "SIBLING_CALL_P (insn) && TARGET_SMALL_EXEC" + "j\t%1" + [(set_attr "op_type" "RI") + (set_attr "type" "branch")]) + +(define_insn "*sibcall_value_brcl" + [(set (match_operand 0 "" "") + (call (mem:QI (match_operand 1 "bras_sym_operand" "X")) + (match_operand 2 "const_int_operand" "n")))] + "SIBLING_CALL_P (insn) && TARGET_CPU_ZARCH" + "jg\t%1" + [(set_attr "op_type" "RIL") + (set_attr "type" "branch")]) + + +; +; call instruction pattern(s). +; + +(define_expand "call" + [(call (match_operand 0 "" "") + (match_operand 1 "" "")) + (use (match_operand 2 "" ""))] "" - "") +{ + s390_emit_call (XEXP (operands[0], 0), NULL_RTX, NULL_RTX, + gen_rtx_REG (Pmode, RETURN_REGNUM)); + DONE; +}) (define_insn "*bras" [(call (mem:QI (match_operand 0 "bras_sym_operand" "X")) (match_operand 1 "const_int_operand" "n")) (clobber (match_operand 2 "register_operand" "=r"))] - "TARGET_SMALL_EXEC && GET_MODE (operands[2]) == Pmode" + "!SIBLING_CALL_P (insn) + && TARGET_SMALL_EXEC + && GET_MODE (operands[2]) == Pmode" "bras\t%2,%0" [(set_attr "op_type" "RI") (set_attr "type" "jsr")]) @@ -6988,7 +7171,9 @@ [(call (mem:QI (match_operand 0 "bras_sym_operand" "X")) (match_operand 1 "const_int_operand" "n")) (clobber (match_operand 2 "register_operand" "=r"))] - "TARGET_CPU_ZARCH && GET_MODE (operands[2]) == Pmode" + "!SIBLING_CALL_P (insn) + && TARGET_CPU_ZARCH + && GET_MODE (operands[2]) == Pmode" "brasl\t%2,%0" [(set_attr "op_type" "RIL") (set_attr "type" "jsr")]) @@ -6997,7 +7182,7 @@ [(call (mem:QI (match_operand 0 "address_operand" "U")) (match_operand 1 "const_int_operand" "n")) (clobber (match_operand 2 "register_operand" "=r"))] - "GET_MODE (operands[2]) == Pmode" + "!SIBLING_CALL_P (insn) && GET_MODE (operands[2]) == Pmode" { if (get_attr_op_type (insn) == OP_TYPE_RR) return "basr\t%2,%0"; @@ -7021,62 +7206,19 @@ (use (match_operand 3 "" ""))] "" { - bool plt_call = false; - rtx insn; - - /* Direct function calls need special treatment. */ - if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF) - { - rtx sym = XEXP (operands[1], 0); - - /* When calling a global routine in PIC mode, we must - replace the symbol itself with the PLT stub. */ - if (flag_pic && !SYMBOL_REF_LOCAL_P (sym)) - { - sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), UNSPEC_PLT); - sym = gen_rtx_CONST (Pmode, sym); - plt_call = true; - } - - /* Unless we can use the bras(l) insn, force the - routine address into a register. */ - if (!TARGET_SMALL_EXEC && !TARGET_CPU_ZARCH) - { - if (flag_pic) - sym = legitimize_pic_address (sym, 0); - else - sym = force_reg (Pmode, sym); - } - - operands[1] = gen_rtx_MEM (QImode, sym); - } - - /* Emit insn. */ - insn = emit_call_insn ( - gen_call_value_exp (operands[0], operands[1], operands[2], - gen_rtx_REG (Pmode, RETURN_REGNUM))); - - /* 31-bit PLT stubs use the GOT register implicitly. */ - if (!TARGET_64BIT && plt_call) - use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx); - + s390_emit_call (XEXP (operands[1], 0), NULL_RTX, operands[0], + gen_rtx_REG (Pmode, RETURN_REGNUM)); DONE; }) -(define_expand "call_value_exp" - [(parallel [(set (match_operand 0 "" "") - (call (match_operand 1 "" "") - (match_operand 2 "" ""))) - (clobber (match_operand 3 "" ""))])] - "" - "") - (define_insn "*bras_r" [(set (match_operand 0 "" "") (call (mem:QI (match_operand 1 "bras_sym_operand" "X")) (match_operand:SI 2 "const_int_operand" "n"))) (clobber (match_operand 3 "register_operand" "=r"))] - "TARGET_SMALL_EXEC && GET_MODE (operands[3]) == Pmode" + "!SIBLING_CALL_P (insn) + && TARGET_SMALL_EXEC + && GET_MODE (operands[3]) == Pmode" "bras\t%3,%1" [(set_attr "op_type" "RI") (set_attr "type" "jsr")]) @@ -7086,7 +7228,9 @@ (call (mem:QI (match_operand 1 "bras_sym_operand" "X")) (match_operand 2 "const_int_operand" "n"))) (clobber (match_operand 3 "register_operand" "=r"))] - "TARGET_CPU_ZARCH && GET_MODE (operands[3]) == Pmode" + "!SIBLING_CALL_P (insn) + && TARGET_CPU_ZARCH + && GET_MODE (operands[3]) == Pmode" "brasl\t%3,%1" [(set_attr "op_type" "RIL") (set_attr "type" "jsr")]) @@ -7096,7 +7240,7 @@ (call (mem:QI (match_operand 1 "address_operand" "U")) (match_operand 2 "const_int_operand" "n"))) (clobber (match_operand 3 "register_operand" "=r"))] - "GET_MODE (operands[3]) == Pmode" + "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode" { if (get_attr_op_type (insn) == OP_TYPE_RR) return "basr\t%3,%1"; @@ -7113,46 +7257,34 @@ ;;- Thread-local storage support. ;; -(define_insn "get_tp_64" - [(set (match_operand:DI 0 "nonimmediate_operand" "=??d,Q") - (unspec:DI [(const_int 0)] UNSPEC_TP))] +(define_expand "get_tp_64" + [(set (match_operand:DI 0 "nonimmediate_operand" "") (reg:DI TP_REGNUM))] "TARGET_64BIT" - "@ - ear\t%0,%%a0\;sllg\t%0,%0,32\;ear\t%0,%%a1 - stam\t%%a0,%%a1,%0" - [(set_attr "op_type" "NN,RS") - (set_attr "atype" "reg,*") - (set_attr "type" "o3,*") - (set_attr "length" "14,*")]) + "") -(define_insn "get_tp_31" - [(set (match_operand:SI 0 "nonimmediate_operand" "=d,Q") - (unspec:SI [(const_int 0)] UNSPEC_TP))] +(define_expand "get_tp_31" + [(set (match_operand:SI 0 "nonimmediate_operand" "") (reg:SI TP_REGNUM))] "!TARGET_64BIT" - "@ - ear\t%0,%%a0 - stam\t%%a0,%%a0,%0" - [(set_attr "op_type" "RRE,RS")]) + "") -(define_insn "set_tp_64" - [(unspec_volatile [(match_operand:DI 0 "general_operand" "??d,Q")] UNSPECV_SET_TP) - (clobber (match_scratch:SI 1 "=d,X"))] +(define_expand "set_tp_64" + [(set (reg:DI TP_REGNUM) (match_operand:DI 0 "nonimmediate_operand" "")) + (set (reg:DI TP_REGNUM) (unspec_volatile:DI [(reg:DI TP_REGNUM)] UNSPECV_SET_TP))] "TARGET_64BIT" - "@ - sar\t%%a1,%0\;srlg\t%1,%0,32\;sar\t%%a0,%1 - lam\t%%a0,%%a1,%0" - [(set_attr "op_type" "NN,RS") - (set_attr "atype" "reg,*") - (set_attr "type" "o3,*") - (set_attr "length" "14,*")]) + "") -(define_insn "set_tp_31" - [(unspec_volatile [(match_operand:SI 0 "general_operand" "d,Q")] UNSPECV_SET_TP)] +(define_expand "set_tp_31" + [(set (reg:SI TP_REGNUM) (match_operand:SI 0 "nonimmediate_operand" "")) + (set (reg:SI TP_REGNUM) (unspec_volatile:SI [(reg:SI TP_REGNUM)] UNSPECV_SET_TP))] "!TARGET_64BIT" - "@ - sar\t%%a0,%0 - lam\t%%a0,%%a0,%0" - [(set_attr "op_type" "RRE,RS")]) + "") + +(define_insn "*set_tp" + [(set (reg TP_REGNUM) (unspec_volatile [(reg TP_REGNUM)] UNSPECV_SET_TP))] + "" + "" + [(set_attr "type" "none") + (set_attr "length" "0")]) (define_insn "*tls_load_64" [(set (match_operand:DI 0 "register_operand" "=d") @@ -7174,64 +7306,15 @@ ly\t%0,%1%J2" [(set_attr "op_type" "RX,RXY")]) -(define_expand "call_value_tls" - [(set (match_operand 0 "" "") - (call (const_int 0) (const_int 0))) - (use (match_operand 1 "" ""))] - "" -{ - rtx insn, sym; - - if (!flag_pic) - abort (); - - sym = s390_tls_get_offset (); - sym = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), UNSPEC_PLT); - sym = gen_rtx_CONST (Pmode, sym); - - /* Unless we can use the bras(l) insn, force the - routine address into a register. */ - if (!TARGET_SMALL_EXEC && !TARGET_CPU_ZARCH) - { - if (flag_pic) - sym = legitimize_pic_address (sym, 0); - else - sym = force_reg (Pmode, sym); - } - - sym = gen_rtx_MEM (QImode, sym); - - /* Emit insn. */ - insn = emit_call_insn ( - gen_call_value_tls_exp (operands[0], sym, const0_rtx, - gen_rtx_REG (Pmode, RETURN_REGNUM), - operands[1])); - - /* The calling convention of __tls_get_offset uses the - GOT register implicitly. */ - use_reg (&CALL_INSN_FUNCTION_USAGE (insn), pic_offset_table_rtx); - use_reg (&CALL_INSN_FUNCTION_USAGE (insn), operands[0]); - CONST_OR_PURE_CALL_P (insn) = 1; - - DONE; -}) - -(define_expand "call_value_tls_exp" - [(parallel [(set (match_operand 0 "" "") - (call (match_operand 1 "" "") - (match_operand 2 "" ""))) - (clobber (match_operand 3 "" "")) - (use (match_operand 4 "" ""))])] - "" - "") - (define_insn "*bras_tls" [(set (match_operand 0 "" "") (call (mem:QI (match_operand 1 "bras_sym_operand" "X")) (match_operand 2 "const_int_operand" "n"))) (clobber (match_operand 3 "register_operand" "=r")) (use (match_operand 4 "" ""))] - "TARGET_SMALL_EXEC && GET_MODE (operands[3]) == Pmode" + "!SIBLING_CALL_P (insn) + && TARGET_SMALL_EXEC + && GET_MODE (operands[3]) == Pmode" "bras\t%3,%1%J4" [(set_attr "op_type" "RI") (set_attr "type" "jsr")]) @@ -7242,7 +7325,9 @@ (match_operand 2 "const_int_operand" "n"))) (clobber (match_operand 3 "register_operand" "=r")) (use (match_operand 4 "" ""))] - "TARGET_CPU_ZARCH && GET_MODE (operands[3]) == Pmode" + "!SIBLING_CALL_P (insn) + && TARGET_CPU_ZARCH + && GET_MODE (operands[3]) == Pmode" "brasl\t%3,%1%J4" [(set_attr "op_type" "RIL") (set_attr "type" "jsr")]) @@ -7253,7 +7338,7 @@ (match_operand 2 "const_int_operand" "n"))) (clobber (match_operand 3 "register_operand" "=r")) (use (match_operand 4 "" ""))] - "GET_MODE (operands[3]) == Pmode" + "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode" { if (get_attr_op_type (insn) == OP_TYPE_RR) return "basr\t%3,%1%J4"; @@ -7267,6 +7352,159 @@ (set_attr "atype" "agen")]) ;; +;;- Atomic operations +;; + +; +; memory barrier pattern. +; + +(define_expand "memory_barrier" + [(set (mem:BLK (match_dup 0)) + (unspec_volatile:BLK [(mem:BLK (match_dup 0))] UNSPECV_MB))] + "" +{ + operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (DImode)); + MEM_VOLATILE_P (operands[0]) = 1; +}) + +(define_insn "*memory_barrier" + [(set (match_operand:BLK 0 "" "") + (unspec_volatile:BLK [(match_operand:BLK 1 "" "")] UNSPECV_MB))] + "" + "bcr\t15,0" + [(set_attr "op_type" "RR")]) + +; +; compare and swap patterns. +; + +(define_expand "sync_compare_and_swap<mode>" + [(parallel + [(set (match_operand:TDSI 0 "register_operand" "") + (match_operand:TDSI 1 "memory_operand" "")) + (set (match_dup 1) + (unspec_volatile:TDSI + [(match_dup 1) + (match_operand:TDSI 2 "register_operand" "") + (match_operand:TDSI 3 "register_operand" "")] + UNSPECV_CAS)) + (set (reg:CCZ1 CC_REGNUM) + (compare:CCZ1 (match_dup 1) (match_dup 2)))])] + "") + +(define_expand "sync_compare_and_swap<mode>" + [(parallel + [(set (match_operand:HQI 0 "register_operand" "") + (match_operand:HQI 1 "memory_operand" "")) + (set (match_dup 1) + (unspec_volatile:HQI + [(match_dup 1) + (match_operand:HQI 2 "general_operand" "") + (match_operand:HQI 3 "general_operand" "")] + UNSPECV_CAS)) + (set (reg:CCZ1 CC_REGNUM) + (compare:CCZ1 (match_dup 1) (match_dup 2)))])] + "" + "s390_expand_cs_hqi (<MODE>mode, operands[0], operands[1], + operands[2], operands[3]); DONE;") + +(define_expand "sync_compare_and_swap_cc<mode>" + [(parallel + [(set (match_operand:TDSI 0 "register_operand" "") + (match_operand:TDSI 1 "memory_operand" "")) + (set (match_dup 1) + (unspec_volatile:TDSI + [(match_dup 1) + (match_operand:TDSI 2 "register_operand" "") + (match_operand:TDSI 3 "register_operand" "")] + UNSPECV_CAS)) + (set (match_dup 4) + (compare:CCZ1 (match_dup 1) (match_dup 2)))])] + "" +{ + /* Emulate compare. */ + operands[4] = gen_rtx_REG (CCZ1mode, CC_REGNUM); + s390_compare_op0 = operands[1]; + s390_compare_op1 = operands[2]; + s390_compare_emitted = operands[4]; +}) + +; cds, cdsg +(define_insn "*sync_compare_and_swap<mode>" + [(set (match_operand:DP 0 "register_operand" "=r") + (match_operand:DP 1 "memory_operand" "+Q")) + (set (match_dup 1) + (unspec_volatile:DP + [(match_dup 1) + (match_operand:DP 2 "register_operand" "0") + (match_operand:DP 3 "register_operand" "r")] + UNSPECV_CAS)) + (set (reg:CCZ1 CC_REGNUM) + (compare:CCZ1 (match_dup 1) (match_dup 2)))] + "" + "cds<tg>\t%0,%3,%S1" + [(set_attr "op_type" "RS<TE>") + (set_attr "type" "sem")]) + +; cs, csg +(define_insn "*sync_compare_and_swap<mode>" + [(set (match_operand:GPR 0 "register_operand" "=r") + (match_operand:GPR 1 "memory_operand" "+Q")) + (set (match_dup 1) + (unspec_volatile:GPR + [(match_dup 1) + (match_operand:GPR 2 "register_operand" "0") + (match_operand:GPR 3 "register_operand" "r")] + UNSPECV_CAS)) + (set (reg:CCZ1 CC_REGNUM) + (compare:CCZ1 (match_dup 1) (match_dup 2)))] + "" + "cs<g>\t%0,%3,%S1" + [(set_attr "op_type" "RS<E>") + (set_attr "type" "sem")]) + + +; +; Other atomic instruction patterns. +; + +(define_expand "sync_lock_test_and_set<mode>" + [(match_operand:HQI 0 "register_operand") + (match_operand:HQI 1 "memory_operand") + (match_operand:HQI 2 "general_operand")] + "" + "s390_expand_atomic (<MODE>mode, SET, operands[0], operands[1], + operands[2], false); DONE;") + +(define_expand "sync_<atomic><mode>" + [(set (match_operand:HQI 0 "memory_operand") + (ATOMIC:HQI (match_dup 0) + (match_operand:HQI 1 "general_operand")))] + "" + "s390_expand_atomic (<MODE>mode, <CODE>, NULL_RTX, operands[0], + operands[1], false); DONE;") + +(define_expand "sync_old_<atomic><mode>" + [(set (match_operand:HQI 0 "register_operand") + (match_operand:HQI 1 "memory_operand")) + (set (match_dup 1) + (ATOMIC:HQI (match_dup 1) + (match_operand:HQI 2 "general_operand")))] + "" + "s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1], + operands[2], false); DONE;") + +(define_expand "sync_new_<atomic><mode>" + [(set (match_operand:HQI 0 "register_operand") + (ATOMIC:HQI (match_operand:HQI 1 "memory_operand") + (match_operand:HQI 2 "general_operand"))) + (set (match_dup 1) (ATOMIC:HQI (match_dup 1) (match_dup 2)))] + "" + "s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1], + operands[2], true); DONE;") + +;; ;;- Miscellaneous instructions. ;; @@ -7275,27 +7513,18 @@ ; (define_expand "allocate_stack" - [(set (reg 15) - (plus (reg 15) (match_operand 1 "general_operand" ""))) - (set (match_operand 0 "general_operand" "") - (reg 15))] + [(match_operand 0 "general_operand" "") + (match_operand 1 "general_operand" "")] "TARGET_BACKCHAIN" { - rtx stack = gen_rtx (REG, Pmode, STACK_POINTER_REGNUM); - rtx chain = gen_rtx (MEM, Pmode, stack); - rtx temp = gen_reg_rtx (Pmode); - - emit_move_insn (temp, chain); - - if (TARGET_64BIT) - emit_insn (gen_adddi3 (stack, stack, negate_rtx (Pmode, operands[1]))); - else - emit_insn (gen_addsi3 (stack, stack, negate_rtx (Pmode, operands[1]))); + rtx temp = gen_reg_rtx (Pmode); - emit_move_insn (chain, temp); + emit_move_insn (temp, s390_back_chain_rtx ()); + anti_adjust_stack (operands[1]); + emit_move_insn (s390_back_chain_rtx (), temp); - emit_move_insn (operands[0], virtual_stack_dynamic_rtx); - DONE; + emit_move_insn (operands[0], virtual_stack_dynamic_rtx); + DONE; }) @@ -7307,7 +7536,7 @@ [(match_operand 0 "" "")] "flag_pic" { - s390_load_got (false); + emit_insn (s390_load_got ()); emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx)); DONE; }) @@ -7334,14 +7563,17 @@ "DONE;") (define_expand "restore_stack_block" - [(use (match_operand 0 "register_operand" "")) - (set (match_dup 2) (match_dup 3)) - (set (match_dup 0) (match_operand 1 "register_operand" "")) - (set (match_dup 3) (match_dup 2))] - "" + [(match_operand 0 "register_operand" "") + (match_operand 1 "register_operand" "")] + "TARGET_BACKCHAIN" { - operands[2] = gen_reg_rtx (Pmode); - operands[3] = gen_rtx_MEM (Pmode, operands[0]); + rtx temp = gen_reg_rtx (Pmode); + + emit_move_insn (temp, s390_back_chain_rtx ()); + emit_move_insn (operands[0], operands[1]); + emit_move_insn (s390_back_chain_rtx (), temp); + + DONE; }) (define_expand "save_stack_nonlocal" @@ -7349,20 +7581,21 @@ (match_operand 1 "register_operand" "")] "" { - rtx temp = gen_reg_rtx (Pmode); + enum machine_mode mode = TARGET_64BIT ? OImode : TImode; + rtx base = gen_rtx_REG (Pmode, BASE_REGNUM); + + /* Copy the backchain to the first word, sp to the second and the + literal pool base to the third. */ + + if (TARGET_BACKCHAIN) + { + rtx temp = force_reg (Pmode, s390_back_chain_rtx ()); + emit_move_insn (operand_subword (operands[0], 0, 0, mode), temp); + } + + emit_move_insn (operand_subword (operands[0], 1, 0, mode), operands[1]); + emit_move_insn (operand_subword (operands[0], 2, 0, mode), base); - /* Copy the backchain to the first word, sp to the second and the literal pool - base to the third. */ - emit_move_insn (operand_subword (operands[0], 2, 0, - TARGET_64BIT ? OImode : TImode), - gen_rtx_REG (Pmode, BASE_REGISTER)); - emit_move_insn (temp, gen_rtx_MEM (Pmode, operands[1])); - emit_move_insn (operand_subword (operands[0], 0, 0, - TARGET_64BIT ? OImode : TImode), - temp); - emit_move_insn (operand_subword (operands[0], 1, 0, - TARGET_64BIT ? OImode : TImode), - operands[1]); DONE; }) @@ -7371,26 +7604,33 @@ (match_operand 1 "memory_operand" "")] "" { - rtx temp = gen_reg_rtx (Pmode); - rtx base = gen_rtx_REG (Pmode, BASE_REGISTER); + enum machine_mode mode = TARGET_64BIT ? OImode : TImode; + rtx base = gen_rtx_REG (Pmode, BASE_REGNUM); + rtx temp = NULL_RTX; /* Restore the backchain from the first word, sp from the second and the - literal pool base from the third. */ - emit_move_insn (temp, - operand_subword (operands[1], 0, 0, - TARGET_64BIT ? OImode : TImode)); - emit_move_insn (operands[0], - operand_subword (operands[1], 1, 0, - TARGET_64BIT ? OImode : TImode)); - emit_move_insn (gen_rtx_MEM (Pmode, operands[0]), temp); - emit_move_insn (base, - operand_subword (operands[1], 2, 0, - TARGET_64BIT ? OImode : TImode)); - emit_insn (gen_rtx_USE (VOIDmode, base)); + literal pool base from the third. */ + + if (TARGET_BACKCHAIN) + temp = force_reg (Pmode, operand_subword (operands[1], 0, 0, mode)); + + emit_move_insn (base, operand_subword (operands[1], 2, 0, mode)); + emit_move_insn (operands[0], operand_subword (operands[1], 1, 0, mode)); + if (temp) + emit_move_insn (s390_back_chain_rtx (), temp); + + emit_insn (gen_rtx_USE (VOIDmode, base)); DONE; }) +(define_expand "exception_receiver" + [(const_int 0)] + "" +{ + s390_set_has_landing_pad_p (true); + DONE; +}) ; ; nop instruction pattern(s). @@ -7414,40 +7654,30 @@ { enum machine_mode mode = GET_MODE (PATTERN (insn)); unsigned int align = GET_MODE_BITSIZE (mode); - s390_output_pool_entry (asm_out_file, operands[0], mode, align); + s390_output_pool_entry (operands[0], mode, align); return ""; } - [(set_attr "op_type" "NN") - (set (attr "length") + [(set (attr "length") (symbol_ref "GET_MODE_SIZE (GET_MODE (PATTERN (insn)))"))]) -(define_insn "pool_start_31" - [(unspec_volatile [(const_int 0)] UNSPECV_POOL_START)] - "!TARGET_CPU_ZARCH" - ".align\t4" - [(set_attr "op_type" "NN") - (set_attr "length" "2")]) - -(define_insn "pool_end_31" - [(unspec_volatile [(const_int 0)] UNSPECV_POOL_END)] - "!TARGET_CPU_ZARCH" - ".align\t2" - [(set_attr "op_type" "NN") - (set_attr "length" "2")]) +(define_insn "pool_align" + [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] + UNSPECV_POOL_ALIGN)] + "" + ".align\t%0" + [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))]) -(define_insn "pool_start_64" - [(unspec_volatile [(const_int 0)] UNSPECV_POOL_START)] - "TARGET_CPU_ZARCH" - ".section\t.rodata\;.align\t8" - [(set_attr "op_type" "NN") - (set_attr "length" "0")]) +(define_insn "pool_section_start" + [(unspec_volatile [(const_int 1)] UNSPECV_POOL_SECTION)] + "" + ".section\t.rodata" + [(set_attr "length" "0")]) -(define_insn "pool_end_64" - [(unspec_volatile [(const_int 0)] UNSPECV_POOL_END)] - "TARGET_CPU_ZARCH" +(define_insn "pool_section_end" + [(unspec_volatile [(const_int 0)] UNSPECV_POOL_SECTION)] + "" ".previous" - [(set_attr "op_type" "NN") - (set_attr "length" "0")]) + [(set_attr "length" "0")]) (define_insn "main_base_31_small" [(set (match_operand 0 "register_operand" "=a") @@ -7474,19 +7704,23 @@ (set_attr "type" "larl")]) (define_insn "main_pool" - [(unspec_volatile [(const_int 0)] UNSPECV_MAIN_POOL)] - "" - "* abort ();" - [(set_attr "op_type" "NN")]) + [(set (match_operand 0 "register_operand" "=a") + (unspec_volatile [(const_int 0)] UNSPECV_MAIN_POOL))] + "GET_MODE (operands[0]) == Pmode" +{ + gcc_unreachable (); +} + [(set (attr "type") + (if_then_else (ne (symbol_ref "TARGET_CPU_ZARCH") (const_int 0)) + (const_string "larl") (const_string "la")))]) (define_insn "reload_base_31" [(set (match_operand 0 "register_operand" "=a") (unspec [(label_ref (match_operand 1 "" ""))] UNSPEC_RELOAD_BASE))] "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode" "basr\t%0,0\;la\t%0,%1-.(%0)" - [(set_attr "op_type" "NN") - (set_attr "type" "la") - (set_attr "length" "6")]) + [(set_attr "length" "6") + (set_attr "type" "la")]) (define_insn "reload_base_64" [(set (match_operand 0 "register_operand" "=a") @@ -7499,9 +7733,10 @@ (define_insn "pool" [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] UNSPECV_POOL)] "" - "* abort ();" - [(set_attr "op_type" "NN") - (set (attr "length") (symbol_ref "INTVAL (operands[0])"))]) +{ + gcc_unreachable (); +} + [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))]) ;; ;; Insns related to generating the function prologue and epilogue. @@ -7516,7 +7751,12 @@ (define_expand "epilogue" [(use (const_int 1))] "" - "s390_emit_epilogue (); DONE;") + "s390_emit_epilogue (false); DONE;") + +(define_expand "sibcall_epilogue" + [(use (const_int 0))] + "" + "s390_emit_epilogue (true); DONE;") (define_insn "*return" [(return) @@ -7541,3 +7781,77 @@ GEN_INT (0x7fffffff))); DONE; }) + +;; Instruction definition to expand eh_return macro to support +;; swapping in special linkage return addresses. + +(define_expand "eh_return" + [(use (match_operand 0 "register_operand" ""))] + "TARGET_TPF" +{ + s390_emit_tpf_eh_return (operands[0]); + DONE; +}) + +; +; Stack Protector Patterns +; + +(define_expand "stack_protect_set" + [(set (match_operand 0 "memory_operand" "") + (match_operand 1 "memory_operand" ""))] + "" +{ +#ifdef TARGET_THREAD_SSP_OFFSET + operands[1] + = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), + GEN_INT (TARGET_THREAD_SSP_OFFSET))); +#endif + if (TARGET_64BIT) + emit_insn (gen_stack_protect_setdi (operands[0], operands[1])); + else + emit_insn (gen_stack_protect_setsi (operands[0], operands[1])); + + DONE; +}) + +(define_insn "stack_protect_set<mode>" + [(set (match_operand:DSI 0 "memory_operand" "=Q") + (unspec:DSI [(match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_SET))] + "" + "mvc\t%O0(%G0,%R0),%S1" + [(set_attr "op_type" "SS")]) + +(define_expand "stack_protect_test" + [(set (reg:CC CC_REGNUM) + (compare (match_operand 0 "memory_operand" "") + (match_operand 1 "memory_operand" ""))) + (match_operand 2 "" "")] + "" +{ +#ifdef TARGET_THREAD_SSP_OFFSET + operands[1] + = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), + GEN_INT (TARGET_THREAD_SSP_OFFSET))); +#endif + s390_compare_op0 = operands[0]; + s390_compare_op1 = operands[1]; + s390_compare_emitted = gen_rtx_REG (CCZmode, CC_REGNUM); + + if (TARGET_64BIT) + emit_insn (gen_stack_protect_testdi (operands[0], operands[1])); + else + emit_insn (gen_stack_protect_testsi (operands[0], operands[1])); + + emit_jump_insn (gen_beq (operands[2])); + + DONE; +}) + +(define_insn "stack_protect_test<mode>" + [(set (reg:CCZ CC_REGNUM) + (unspec:CCZ [(match_operand:DSI 0 "memory_operand" "Q") + (match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_TEST))] + "" + "clc\t%O0(%G0,%R0),%S1" + [(set_attr "op_type" "SS")]) |