From 65b1d8ea3ed53d03f92a614c93faf637fa708772 Mon Sep 17 00:00:00 2001 From: Andreas Krebbel Date: Tue, 5 Oct 2010 10:39:48 +0000 Subject: [PATCH] s390.c (z196_cost): New. 2010-10-05 Andreas Krebbel Christian Borntraeger * gcc/config/s390/s390.c (z196_cost): New. (s390_handle_arch_option): Add -march=z196. (s390_option_override): Use the new cost function and use the z10 defaults also for z196. (legitimate_reload_constant_p): Adjust comment. (legitimate_reload_fp_constant_p): New function. (s390_preferred_reload_class): Distingiush between FP and Int constants. (preferred_la_operand_p): Avoid la with index on z196. (s390_adjust_priority): Trigger also for z196. (s390_issue_rate): Issue rate for z196 is 3. (s390_z10_fix_long_loop_prediction): Rename to ... (s390_fix_long_loop_prediction): ... this. (s390_reorg): Apply the z10 adjustments also for z196. (s390_loop_unroll_adjust): Do this also for z196. * gcc/config/s390/s390.h (enum processor_type): Add PROCESSOR_2817_Z196. (enum processor_flags): Add PF_Z196. (TARGET_AVOID_CMP_AND_BRANCH): New macro. (TARGET_CPU_Z196, TARGET_Z196): New macros. * gcc/config.gcc: Enable z196 for --with-arch. * gcc/config/s390/2817.md: New file. * gcc/config/s390/2084.md: New type for multiply and add. * gcc/config/s390/2097.md: Likewise. * gcc/config/s390/s390.md (UNSPEC_POPCNT, UNSPEC_COPYSIGN) (UNSPECV_ATOMIC_OP): New constants. (fmadddf, fmaddsf): New values for type attribute. (z196prop): New insn attribute. (cpu, cpu_facility): Add z196. (ATOMIC_Z196): New code iterator. (noxa): New code attribute. (gk): New mode attribute. (*mov_64, *mov_31, *mov_64dfp, mov): Support load zero for fp constants. (fixuns_truncdddi2, fixuns_trunctddi2) (fixuns_trunc2): Use the standard rtx pattern for z196. (fixuns_truncsi2, movcc, popcountdi2, popcountsi2) (popcounthi2, popcountqi2): New expander. (*fixuns_trunc2_z196, floatsi2) (floatuns2, *movcc, sync_) (sync_old_, *popcount, copysign3): New insn definition. (add3, *add3_carry1_cc, *add3_carry1_cconly) (*add3_carry2_cc, *add3_carry2_cconly, *add3_cc) (*add3_cconly, *add3_cconly2, *add3_imm_cc, *sub3) (*sub3_borrow_cc, *sub3_borrow_cconly, *sub3_cc) (*sub3_cc2, *sub3_cconly, *sub3_cconly2) (*anddi3_cc, *anddi3_cconly, *anddi3, *andsi3_cc, *andsi3_cconly) (*andsi3_zarch, *andsi3_esa, *andhi3_zarch, *andqi3_zarch, *iordi3_cc) (*iordi3_cconly, *iordi3, *iorsi3_cc, *iorsi3_cconly, *iorsi3_zarch) (*iorhi3_zarch, *iorqi3_zarch, *xordi3_cc, *xordi3_cconly, *xordi3) (*xorsi3_cc, *xorsi3_cconly, *xorsi3, *xorhi3, *xorqi3, *3) (*3_and, *ashr3_cc, *ashr3_cconly, *ashr3) (*ashr3_cc_and, *ashr3_cconly_and, *ashr3_and): Support new z196 instructions. Co-Authored-By: Christian Borntraeger From-SVN: r164985 --- gcc/ChangeLog | 58 ++ gcc/config.gcc | 2 +- gcc/config/s390/2084.md | 4 +- gcc/config/s390/2097.md | 4 +- gcc/config/s390/2817.md | 313 ++++++++++ gcc/config/s390/s390.c | 120 +++- gcc/config/s390/s390.h | 11 +- gcc/config/s390/s390.md | 1296 +++++++++++++++++++++++++-------------- 8 files changed, 1329 insertions(+), 479 deletions(-) create mode 100644 gcc/config/s390/2817.md diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c06867447c42..00c90b9690d5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,61 @@ +2010-10-05 Andreas Krebbel + Christian Borntraeger + + * gcc/config/s390/s390.c (z196_cost): New. + (s390_handle_arch_option): Add -march=z196. + (s390_option_override): Use the new cost function and use the z10 + defaults also for z196. + (legitimate_reload_constant_p): Adjust comment. + (legitimate_reload_fp_constant_p): New function. + (s390_preferred_reload_class): Distingiush between FP and Int constants. + (preferred_la_operand_p): Avoid la with index on z196. + (s390_adjust_priority): Trigger also for z196. + (s390_issue_rate): Issue rate for z196 is 3. + (s390_z10_fix_long_loop_prediction): Rename to ... + (s390_fix_long_loop_prediction): ... this. + (s390_reorg): Apply the z10 adjustments also for z196. + (s390_loop_unroll_adjust): Do this also for z196. + * gcc/config/s390/s390.h (enum processor_type): Add PROCESSOR_2817_Z196. + (enum processor_flags): Add PF_Z196. + (TARGET_AVOID_CMP_AND_BRANCH): New macro. + (TARGET_CPU_Z196, TARGET_Z196): New macros. + * gcc/config.gcc: Enable z196 for --with-arch. + * gcc/config/s390/2817.md: New file. + * gcc/config/s390/2084.md: New type for multiply and add. + * gcc/config/s390/2097.md: Likewise. + * gcc/config/s390/s390.md (UNSPEC_POPCNT, UNSPEC_COPYSIGN) + (UNSPECV_ATOMIC_OP): New constants. + (fmadddf, fmaddsf): New values for type attribute. + (z196prop): New insn attribute. + (cpu, cpu_facility): Add z196. + (ATOMIC_Z196): New code iterator. + (noxa): New code attribute. + (gk): New mode attribute. + (*mov_64, *mov_31, *mov_64dfp, mov): + Support load zero for fp constants. + (fixuns_truncdddi2, fixuns_trunctddi2) + (fixuns_trunc2): Use the standard rtx pattern + for z196. + (fixuns_truncsi2, movcc, popcountdi2, popcountsi2) + (popcounthi2, popcountqi2): New expander. + (*fixuns_trunc2_z196, floatsi2) + (floatuns2, *movcc, sync_) + (sync_old_, *popcount, copysign3): New + insn definition. + (add3, *add3_carry1_cc, *add3_carry1_cconly) + (*add3_carry2_cc, *add3_carry2_cconly, *add3_cc) + (*add3_cconly, *add3_cconly2, *add3_imm_cc, *sub3) + (*sub3_borrow_cc, *sub3_borrow_cconly, *sub3_cc) + (*sub3_cc2, *sub3_cconly, *sub3_cconly2) + (*anddi3_cc, *anddi3_cconly, *anddi3, *andsi3_cc, *andsi3_cconly) + (*andsi3_zarch, *andsi3_esa, *andhi3_zarch, *andqi3_zarch, *iordi3_cc) + (*iordi3_cconly, *iordi3, *iorsi3_cc, *iorsi3_cconly, *iorsi3_zarch) + (*iorhi3_zarch, *iorqi3_zarch, *xordi3_cc, *xordi3_cconly, *xordi3) + (*xorsi3_cc, *xorsi3_cconly, *xorsi3, *xorhi3, *xorqi3, *3) + (*3_and, *ashr3_cc, *ashr3_cconly, *ashr3) + (*ashr3_cc_and, *ashr3_cconly_and, *ashr3_and): + Support new z196 instructions. + 2010-10-05 Richard Guenther PR middle-end/45877 diff --git a/gcc/config.gcc b/gcc/config.gcc index b1e86a044f62..b813ca34be49 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -3374,7 +3374,7 @@ case "${target}" in for which in arch tune; do eval "val=\$with_$which" case ${val} in - "" | g5 | g6 | z900 | z990 | z9-109 | z9-ec | z10) + "" | g5 | g6 | z900 | z990 | z9-109 | z9-ec | z10 | z196) # OK ;; *) diff --git a/gcc/config/s390/2084.md b/gcc/config/s390/2084.md index bedc5c322ba4..bd0e27194b57 100644 --- a/gcc/config/s390/2084.md +++ b/gcc/config/s390/2084.md @@ -168,12 +168,12 @@ (define_insn_reservation "x_fsimpdf" 6 (and (eq_attr "cpu" "z990,z9_109") - (eq_attr "type" "fsimpdf,fmuldf,fhex")) + (eq_attr "type" "fsimpdf,fmuldf,fmadddf,fhex")) "x_e1_t,x-wr-fp") (define_insn_reservation "x_fsimpsf" 6 (and (eq_attr "cpu" "z990,z9_109") - (eq_attr "type" "fsimpsf,fmulsf,fhex")) + (eq_attr "type" "fsimpsf,fmulsf,fmaddsf,fhex")) "x_e1_t,x-wr-fp") diff --git a/gcc/config/s390/2097.md b/gcc/config/s390/2097.md index fa61038e763b..d138ebb4d3e7 100644 --- a/gcc/config/s390/2097.md +++ b/gcc/config/s390/2097.md @@ -463,12 +463,12 @@ (define_insn_reservation "z10_fsimpdf" 6 (and (eq_attr "cpu" "z10") - (eq_attr "type" "fsimpdf,fmuldf")) + (eq_attr "type" "fsimpdf,fmuldf,fmadddf")) "z10_e1_BOTH, z10_Gate_FP") (define_insn_reservation "z10_fsimpsf" 6 (and (eq_attr "cpu" "z10") - (eq_attr "type" "fsimpsf,fmulsf")) + (eq_attr "type" "fsimpsf,fmulsf,fmaddsf")) "z10_e1_BOTH, z10_Gate_FP") (define_insn_reservation "z10_fmultf" 52 diff --git a/gcc/config/s390/2817.md b/gcc/config/s390/2817.md new file mode 100644 index 000000000000..9bd4e1a449c0 --- /dev/null +++ b/gcc/config/s390/2817.md @@ -0,0 +1,313 @@ +;; Scheduling description for z196 (cpu 2817). +;; Copyright (C) 2010 +;; Free Software Foundation, Inc. +;; Contributed by Christian Borntraeger (Christian.Borntraeger@de.ibm.com) +;; Andreas Krebbel (Andreas.Krebbel@de.ibm.com) + +;; This file is part of GCC. + +;; GCC is free software; you can redistribute it and/or modify it under +;; the terms of the GNU General Public License as published by the Free +;; Software Foundation; either version 3, or (at your option) any later +;; version. + +;; GCC is distributed in the hope that it will be useful, but WITHOUT ANY +;; WARRANTY; without even the implied warranty of MERCHANTABILITY or +;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +;; for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +(define_automaton "z196_ipu") + +;; Fetch + Decoder +(define_cpu_unit "z196_g1" "z196_ipu") +(define_cpu_unit "z196_g2" "z196_ipu") +(define_cpu_unit "z196_g3" "z196_ipu") +(define_cpu_unit "z196_cr1" "z196_ipu") +(define_cpu_unit "z196_cr2" "z196_ipu") +(define_cpu_unit "z196_cr3" "z196_ipu") + +(final_presence_set "z196_g2" "z196_g1") +(final_presence_set "z196_g3" "z196_g2") +(final_presence_set "z196_cr2" "z196_cr1") +(final_presence_set "z196_cr3" "z196_cr2") +(exclusion_set "z196_g1" "z196_cr1") + +;; Instructions can be groupable, end a group, or be alone in a group. +(define_reservation "z196_simple" "( z196_g1 | z196_g2 | z196_g3 )") +(define_reservation "z196_ends" "( z196_g3 | ( z196_g2 + z196_g3 ) | ( z196_g1 + z196_g2 + z196_g3 ) )") + +;; Try to keep cracked and alone ops together in a clump. +(define_reservation "z196_crack" "( z196_cr1 | z196_cr2 | z196_cr3 )") +(define_reservation "z196_alone" "( z196_cr1 | z196_cr2 | z196_cr3 )") + +;; Most simple instruction a fast enough to be handled by OOO even with +;; latency == 0. This reduces life ranges and spilling. We want to increase +;; life range for longer running ops, though, thats why we do not use +;; -fno-schedule-insns. +(define_insn_reservation "z196_simple_LSU" 0 + (and (eq_attr "cpu" "z196") + (and (eq_attr "type" "load,store,lr") + (eq_attr "z196prop" "none"))) + "z196_simple") + +(define_insn_reservation "z196_simple_FXU" 0 + (and (eq_attr "cpu" "z196") + (and (eq_attr "type" "integer,la,larl,other") + (and (eq_attr "z196prop" "none") + (eq_attr "op_type" "RR")))) + "z196_simple") + +(define_insn_reservation "z196_simple_DUAL" 0 + (and (eq_attr "cpu" "z196") + (and (eq_attr "type" "integer,la,larl,other") + (and (eq_attr "z196prop" "none") + (eq_attr "op_type" "!RR")))) + "z196_simple") + +(define_insn_reservation "z196_cracked" 0 + (and (eq_attr "cpu" "z196") + (and (eq_attr "type" "integer,la,larl,load,lr,store,other") + (eq_attr "z196prop" "z196_cracked"))) + "z196_crack") + +(define_insn_reservation "z196_alone" 0 + (and (eq_attr "cpu" "z196") + (and (eq_attr "type" "integer,la,larl,load,lr,store,other") + (eq_attr "z196prop" "z196_alone"))) + "z196_alone") + +(define_insn_reservation "z196_ends" 0 + (and (eq_attr "cpu" "z196") + (and (eq_attr "type" "integer,la,larl,load,lr,store,other") + (eq_attr "z196prop" "z196_ends"))) + "z196_ends") + +(define_insn_reservation "z196_branch" 0 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "branch")) + "z196_ends") + +(define_insn_reservation "z196_call" 0 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "jsr")) + "z196_ends") + +(define_insn_reservation "z196_mul_hi" 10 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "imulhi")) + "z196_simple") + +(define_insn_reservation "z196_mul_si" 12 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "imulsi")) + "z196_simple") + +(define_insn_reservation "z196_mul_di" 14 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "imuldi")) + "z196_simple") + +(define_insn_reservation "z196_div" 73 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "idiv")) + "z196_alone") + +(define_insn_reservation "z196_sem" 0 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "sem")) + "z196_crack") + +(define_insn_reservation "z196_cs" 0 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "cs")) + "z196_crack") + +(define_insn_reservation "z196_vs" 0 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "vs")) + "z196_alone") + +(define_insn_reservation "z196_lm_stm" 0 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "stm,lm")) + "z196_crack") + + +;; +;; Binary Floating Point +;; + +(define_insn_reservation "z196_fsimptf" 18 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "fsimptf,fhex")) + "z196_alone") + +(define_insn_reservation "z196_fmultf" 47 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "fmultf")) + "z196_alone") + +(define_insn_reservation "z196_fsimpdf" 7 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "fsimpdf,fmuldf,fhex")) + "z196_simple") + +(define_insn_reservation "z196_fmadddf" 7 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "fmadddf")) + "z196_alone") + +(define_insn_reservation "z196_fsimpsf" 7 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "fsimpsf,fmulsf,fhex")) + "z196_simple") + +(define_insn_reservation "z196_fmaddsf" 7 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "fmaddsf")) + "z196_alone") + +(define_insn_reservation "z196_fdivtf" 108 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "fdivtf,fsqrttf")) + "z196_alone") + +(define_insn_reservation "z196_fdivdf" 36 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "fdivdf,fsqrtdf")) + "z196_simple") + +(define_insn_reservation "z196_fdivsf" 29 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "fdivsf,fsqrtsf")) + "z196_simple") + + +;; Loads and stores are cheap as well. +(define_insn_reservation "z196_floaddf" 0 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "floaddf")) + "z196_simple") + +(define_insn_reservation "z196_floadsf" 0 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "floadsf")) + "z196_simple") + +(define_insn_reservation "z196_fstoredf" 0 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "fstoredf")) + "z196_simple") + +(define_insn_reservation "z196_fstoresf" 0 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "fstoresf")) + "z196_simple") + + +(define_insn_reservation "z196_ftrunctf" 9 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "ftrunctf")) + "z196_simple") + +(define_insn_reservation "z196_ftruncdf" 7 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "ftruncdf")) + "z196_simple") + + +(define_insn_reservation "z196_ftoi" 7 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "ftoi")) + "z196_crack") + +(define_insn_reservation "z196_itof" 7 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "itoftf,itofdf,itofsf")) + "z196_crack") + +;; +;; Decimal Floating Point +;; + +;; DDTR +(define_insn_reservation "z196_fdivdd" 33 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "fdivdd")) + "z196_simple") + +;; DXTR +(define_insn_reservation "z196_fdivtd" 35 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "fdivtd")) + "z196_alone") + +;; LEDTR +(define_insn_reservation "z196_ftruncsd" 34 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "ftruncsd")) + "z196_simple") + +;; LDXTR +(define_insn_reservation "z196_ftruncdd" 36 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "ftruncdd")) + "z196_simple") + +;; These are normal fp loads/stores - which are cheap. +(define_insn_reservation "z196_floadsddd" 0 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "floadsd,floaddd,fstoredd,fstoresd")) + "z196_simple") + +;; MDTR +(define_insn_reservation "z196_fmuldd" 23 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "fmuldd")) + "z196_simple") + +;; MXTR +(define_insn_reservation "z196_fmultd" 25 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "fmultd")) + "z196_alone") + +;; multiple different isns like add, sub etc. +;; Just use the same defaults as z10. +(define_insn_reservation "z196_fsimpsd" 17 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "fsimpsd")) + "z196_simple") +(define_insn_reservation "z196_fsimpdd" 17 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "fsimpdd")) + "z196_simple") +(define_insn_reservation "z196_fsimptd" 18 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "fsimptd")) + "z196_alone") + +;; CDGTR +(define_insn_reservation "z196_itofdd" 45 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "itofdd")) + "z196_crack") + +;; CXGTR +(define_insn_reservation "z196_itoftd" 33 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "itoftd")) + "z196_crack") + +;; CGXTR, CGDTR +(define_insn_reservation "z196_ftoidfp" 33 + (and (eq_attr "cpu" "z196") + (eq_attr "type" "ftoidfp")) + "z196_crack") + + + diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 11e9fe2e724c..7fec1b9bcc2c 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -223,6 +223,38 @@ struct processor_costs z10_cost = COSTS_N_INSNS (71), /* DSGR */ }; +static const +struct processor_costs z196_cost = +{ + COSTS_N_INSNS (7), /* M */ + COSTS_N_INSNS (5), /* MGHI */ + COSTS_N_INSNS (5), /* MH */ + COSTS_N_INSNS (5), /* MHI */ + COSTS_N_INSNS (7), /* ML */ + COSTS_N_INSNS (7), /* MR */ + COSTS_N_INSNS (6), /* MS */ + COSTS_N_INSNS (8), /* MSG */ + COSTS_N_INSNS (6), /* MSGF */ + COSTS_N_INSNS (6), /* MSGFR */ + COSTS_N_INSNS (8), /* MSGR */ + COSTS_N_INSNS (6), /* MSR */ + COSTS_N_INSNS (1) , /* multiplication in DFmode */ + COSTS_N_INSNS (40), /* MXBR B+40 */ + COSTS_N_INSNS (100), /* SQXBR B+100 */ + COSTS_N_INSNS (42), /* SQDBR B+42 */ + COSTS_N_INSNS (28), /* SQEBR B+28 */ + COSTS_N_INSNS (1), /* MADBR B */ + COSTS_N_INSNS (1), /* MAEBR B */ + COSTS_N_INSNS (101), /* DXBR B+101 */ + COSTS_N_INSNS (29), /* DDBR */ + COSTS_N_INSNS (22), /* DEBR */ + COSTS_N_INSNS (160), /* DLGR cracked */ + COSTS_N_INSNS (160), /* DLR cracked */ + COSTS_N_INSNS (160), /* DR expanded */ + COSTS_N_INSNS (160), /* DSGFR cracked */ + COSTS_N_INSNS (160), /* DSGR cracked */ +}; + extern int reload_completed; /* Kept up to date using the SCHED_VARIABLE_ISSUE hook. */ @@ -350,8 +382,8 @@ struct GTY(()) machine_function (HARD_REGNO_NREGS ((REGNO), (MODE)) == 1 || !((REGNO) & 1)) /* That's the read ahead of the dynamic branch prediction unit in - bytes on a z10 CPU. */ -#define Z10_PREDICT_DISTANCE 384 + bytes on a z10 (or higher) CPU. */ +#define PREDICT_DISTANCE (TARGET_Z10 ? 384 : 2048) static enum machine_mode s390_libgcc_cmp_return_mode (void) @@ -1506,7 +1538,9 @@ s390_handle_arch_option (const char *arg, {"z9-ec", PROCESSOR_2094_Z9_109, PF_IEEE_FLOAT | PF_ZARCH | PF_LONG_DISPLACEMENT | PF_EXTIMM | PF_DFP }, {"z10", PROCESSOR_2097_Z10, PF_IEEE_FLOAT | PF_ZARCH - | PF_LONG_DISPLACEMENT | PF_EXTIMM | PF_DFP | PF_Z10}, + | PF_LONG_DISPLACEMENT | PF_EXTIMM | PF_DFP | PF_Z10}, + {"z196", PROCESSOR_2817_Z196, PF_IEEE_FLOAT | PF_ZARCH + | PF_LONG_DISPLACEMENT | PF_EXTIMM | PF_DFP | PF_Z10 | PF_Z196 }, }; size_t i; @@ -1624,6 +1658,8 @@ s390_option_override (void) break; case PROCESSOR_2097_Z10: s390_cost = &z10_cost; + case PROCESSOR_2817_Z196: + s390_cost = &z196_cost; break; default: s390_cost = &z900_cost; @@ -1648,7 +1684,8 @@ s390_option_override (void) target_flags |= MASK_LONG_DOUBLE_128; #endif - if (s390_tune == PROCESSOR_2097_Z10) + if (s390_tune == PROCESSOR_2097_Z10 + || s390_tune == PROCESSOR_2817_Z196) { if (!PARAM_SET_P (PARAM_MAX_UNROLLED_INSNS)) set_param_value ("max-unrolled-insns", 100); @@ -2782,7 +2819,9 @@ s390_cannot_force_const_mem (rtx x) operand during and after reload. The difference to legitimate_constant_p is that this function will not accept a constant that would need to be forced to the literal pool - before it can be used as operand. */ + before it can be used as operand. + This function accepts all constants which can be loaded directly + into a GPR. */ bool legitimate_reload_constant_p (rtx op) @@ -2836,6 +2875,24 @@ legitimate_reload_constant_p (rtx op) return false; } +/* Returns true if the constant value OP is a legitimate fp operand + during and after reload. + This function accepts all constants which can be loaded directly + into an FPR. */ + +static bool +legitimate_reload_fp_constant_p (rtx op) +{ + /* Accept floating-point zero operands if the load zero instruction + can be used. */ + if (TARGET_Z196 + && GET_CODE (op) == CONST_DOUBLE + && s390_float_const_zero_p (op)) + return true; + + return false; +} + /* Given an rtx OP being reloaded into a reg required to be in class RCLASS, return the class of reg to actually use. */ @@ -2854,8 +2911,10 @@ s390_preferred_reload_class (rtx op, enum reg_class rclass) else if (reg_class_subset_p (ADDR_REGS, rclass) && legitimate_reload_constant_p (op)) return ADDR_REGS; - else - return NO_REGS; + else if (reg_class_subset_p (FP_REGS, rclass) + && legitimate_reload_fp_constant_p (op)) + return FP_REGS; + return NO_REGS; /* If a symbolic constant or a PLUS is reloaded, it is most likely being used as an address, so @@ -3218,6 +3277,11 @@ preferred_la_operand_p (rtx op1, rtx op2) if (addr.indx && !REGNO_OK_FOR_INDEX_P (REGNO (addr.indx))) return false; + /* Avoid LA instructions with index register on z196; it is + preferable to use regular add instructions when possible. */ + if (addr.indx && s390_tune == PROCESSOR_2817_Z196) + return false; + if (!TARGET_64BIT && !addr.pointer) return false; @@ -5398,8 +5462,6 @@ s390_agen_dep_p (rtx dep_insn, rtx insn) A STD instruction should be scheduled earlier, in order to use the bypass. */ - - static int s390_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority) { @@ -5408,7 +5470,8 @@ s390_adjust_priority (rtx insn ATTRIBUTE_UNUSED, int priority) if (s390_tune != PROCESSOR_2084_Z990 && s390_tune != PROCESSOR_2094_Z9_109 - && s390_tune != PROCESSOR_2097_Z10) + && s390_tune != PROCESSOR_2097_Z10 + && s390_tune != PROCESSOR_2817_Z196) return priority; switch (s390_safe_attr_type (insn)) @@ -5437,6 +5500,7 @@ s390_issue_rate (void) { case PROCESSOR_2084_Z990: case PROCESSOR_2094_Z9_109: + case PROCESSOR_2817_Z196: return 3; case PROCESSOR_2097_Z10: return 2; @@ -9859,13 +9923,13 @@ s390_optimize_prologue (void) } } -/* On z10 the dynamic branch prediction must see the backward jump in - a window of 384 bytes. If not it falls back to the static - prediction. This function rearranges the loop backward branch in a - way which makes the static prediction always correct. The function - returns true if it added an instruction. */ +/* On z10 and later the dynamic branch prediction must see the + backward jump within a certain windows. If not it falls back to + the static prediction. This function rearranges the loop backward + branch in a way which makes the static prediction always correct. + The function returns true if it added an instruction. */ static bool -s390_z10_fix_long_loop_prediction (rtx insn) +s390_fix_long_loop_prediction (rtx insn) { rtx set = single_set (insn); rtx code_label, label_ref, new_label; @@ -9891,11 +9955,11 @@ s390_z10_fix_long_loop_prediction (rtx insn) if (INSN_ADDRESSES (INSN_UID (code_label)) == -1 || INSN_ADDRESSES (INSN_UID (insn)) == -1 || (INSN_ADDRESSES (INSN_UID (insn)) - - INSN_ADDRESSES (INSN_UID (code_label)) < Z10_PREDICT_DISTANCE)) + - INSN_ADDRESSES (INSN_UID (code_label)) < PREDICT_DISTANCE)) return false; for (distance = 0, cur_insn = PREV_INSN (insn); - distance < Z10_PREDICT_DISTANCE - 6; + distance < PREDICT_DISTANCE - 6; distance += get_attr_length (cur_insn), cur_insn = PREV_INSN (cur_insn)) if (!cur_insn || JUMP_P (cur_insn) || LABEL_P (cur_insn)) return false; @@ -10195,8 +10259,9 @@ s390_reorg (void) /* Try to optimize prologue and epilogue further. */ s390_optimize_prologue (); - /* Walk over the insns and do some z10 specific changes. */ - if (s390_tune == PROCESSOR_2097_Z10) + /* Walk over the insns and do some >=z10 specific changes. */ + if (s390_tune == PROCESSOR_2097_Z10 + || s390_tune == PROCESSOR_2817_Z196) { rtx insn; bool insn_added_p = false; @@ -10211,10 +10276,11 @@ s390_reorg (void) continue; if (JUMP_P (insn)) - insn_added_p |= s390_z10_fix_long_loop_prediction (insn); + insn_added_p |= s390_fix_long_loop_prediction (insn); - if (GET_CODE (PATTERN (insn)) == PARALLEL - || GET_CODE (PATTERN (insn)) == SET) + if ((GET_CODE (PATTERN (insn)) == PARALLEL + || GET_CODE (PATTERN (insn)) == SET) + && s390_tune == PROCESSOR_2097_Z10) insn_added_p |= s390_z10_optimize_cmp (insn); } @@ -10360,8 +10426,9 @@ check_dpu (rtx *x, unsigned *mem_count) } /* This target hook implementation for TARGET_LOOP_UNROLL_ADJUST calculates - a new number struct loop *loop should be unrolled if tuned for the z10 - cpu. The loop is analyzed for memory accesses by calling check_dpu for + a new number struct loop *loop should be unrolled if tuned for cpus with + a built-in stride prefetcher. + The loop is analyzed for memory accesses by calling check_dpu for each rtx of the loop. Depending on the loop_depth and the amount of memory accesses a new number <=nunroll is returned to improve the behaviour of the hardware prefetch unit. */ @@ -10373,8 +10440,7 @@ s390_loop_unroll_adjust (unsigned nunroll, struct loop *loop) unsigned i; unsigned mem_count = 0; - /* Only z10 needs special handling. */ - if (s390_tune != PROCESSOR_2097_Z10) + if (s390_tune != PROCESSOR_2097_Z10 && s390_tune != PROCESSOR_2817_Z196) return nunroll; /* Count the number of memory references within the loop body. */ diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h index 8c8554f96e07..ca04a7c55874 100644 --- a/gcc/config/s390/s390.h +++ b/gcc/config/s390/s390.h @@ -36,6 +36,7 @@ enum processor_type PROCESSOR_2084_Z990, PROCESSOR_2094_Z9_109, PROCESSOR_2097_Z10, + PROCESSOR_2817_Z196, PROCESSOR_max }; @@ -48,7 +49,8 @@ enum processor_flags PF_LONG_DISPLACEMENT = 4, PF_EXTIMM = 8, PF_DFP = 16, - PF_Z10 = 32 + PF_Z10 = 32, + PF_Z196 = 64 }; extern enum processor_type s390_tune; @@ -77,6 +79,8 @@ extern int s390_arch_flags; (s390_arch_flags & PF_DFP) #define TARGET_CPU_Z10 \ (s390_arch_flags & PF_Z10) +#define TARGET_CPU_Z196 \ + (s390_arch_flags & PF_Z196) /* These flags indicate that the generated code should run on a cpu providing the respective hardware facility when run in @@ -90,6 +94,11 @@ extern int s390_arch_flags; (TARGET_ZARCH && TARGET_CPU_DFP && TARGET_HARD_FLOAT) #define TARGET_Z10 \ (TARGET_ZARCH && TARGET_CPU_Z10) +#define TARGET_Z196 \ + (TARGET_ZARCH && TARGET_CPU_Z196) + + +#define TARGET_AVOID_CMP_AND_BRANCH (s390_tune == PROCESSOR_2817_Z196) /* Run-time target specification. */ diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 80cb43ad2e30..6d03923a5425 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -107,6 +107,10 @@ ; Test Data Class (TDC) (UNSPEC_TDC_INSN 800) + + ; Population Count + (UNSPEC_POPCNT 900) + (UNSPEC_COPYSIGN 901) ]) ;; @@ -133,6 +137,7 @@ ; Atomic Support (UNSPECV_CAS 700) + (UNSPECV_ATOMIC_OP 701) ]) ;; @@ -203,6 +208,7 @@ floadtf,floaddf,floadsf,fstoredf,fstoresf, fmultf,fmuldf,fmulsf,fdivtf,fdivdf,fdivsf, ftoi,fsqrttf,fsqrtdf,fsqrtsf, + fmadddf,fmaddsf, ftrunctf,ftruncdf, ftruncsd, ftruncdd, itoftf, itofdf, itofsf, itofdd, itoftd, fdivdd, fdivtd, floaddd, floadsd, fmuldd, fmultd, @@ -244,6 +250,14 @@ z10_c" (const_string "none")) +;; Properties concerning Z196 decoding +;; z196_alone: must group alone +;; z196_end: ends a group +;; z196_cracked: instruction is cracked or expanded +(define_attr "z196prop" "none, + z196_alone, z196_ends, + z196_cracked" + (const_string "none")) ;; Length in bytes. @@ -258,10 +272,10 @@ ;; distinguish between g5 and g6, but there are differences between the two ;; CPUs could in theory be modeled. -(define_attr "cpu" "g5,g6,z900,z990,z9_109,z10" +(define_attr "cpu" "g5,g6,z900,z990,z9_109,z10,z196" (const (symbol_ref "s390_tune_attr"))) -(define_attr "cpu_facility" "standard,ieee,zarch,longdisp,extimm,dfp,z10" +(define_attr "cpu_facility" "standard,ieee,zarch,longdisp,extimm,dfp,z10,z196" (const_string "standard")) (define_attr "enabled" "" @@ -290,6 +304,10 @@ (and (eq_attr "cpu_facility" "z10") (ne (symbol_ref "TARGET_Z10") (const_int 0))) + (const_int 1) + + (and (eq_attr "cpu_facility" "z196") + (ne (symbol_ref "TARGET_Z196") (const_int 0))) (const_int 1)] (const_int 0))) @@ -303,6 +321,9 @@ ;; Pipeline description for z10 (include "2097.md") +;; Pipeline description for z196 +(include "2817.md") + ;; Predicates (include "predicates.md") @@ -361,8 +382,10 @@ ;; This iterator and attribute allow to combine most atomic operations. (define_code_iterator ATOMIC [and ior xor plus minus mult]) +(define_code_iterator ATOMIC_Z196 [and ior xor plus]) (define_code_attr atomic [(and "and") (ior "ior") (xor "xor") (plus "add") (minus "sub") (mult "nand")]) +(define_code_attr noxa [(and "n") (ior "o") (xor "x") (plus "a")]) ;; In FP templates, a string like "ltbr" will expand to "ltxbr" in ;; TF/TDmode, "ltdbr" in DF/DDmode, and "ltebr" in SF/SDmode. @@ -464,6 +487,11 @@ ;; and "cfdbr" in SImode. (define_mode_attr gf [(DI "g") (SI "f")]) +;; In GPR templates, a string like sll will expand to sllg for DI +;; and sllk for SI. This way it is possible to merge the new z196 SI +;; 3 operands shift instructions into the existing patterns. +(define_mode_attr gk [(DI "g") (SI "k")]) + ;; ICM mask required to load MODE value into the lowest subreg ;; of a SImode register. (define_mode_attr icm_lo [(HI "3") (QI "1")]) @@ -775,7 +803,8 @@ chrl\t%0,%1" [(set_attr "op_type" "RX,RXY,RIL") (set_attr "cpu_facility" "*,*,z10") - (set_attr "type" "*,*,larl")]) + (set_attr "type" "*,*,larl") + (set_attr "z196prop" "z196_cracked,z196_cracked,z196_cracked")]) (define_insn "*cmphi_ccs_z10" [(set (reg CC_REGNUM) @@ -783,7 +812,8 @@ (match_operand:HI 1 "immediate_operand" "K")))] "s390_match_ccmode(insn, CCSmode) && TARGET_Z10" "chhsi\t%0,%1" - [(set_attr "op_type" "SIL")]) + [(set_attr "op_type" "SIL") + (set_attr "z196prop" "z196_cracked")]) (define_insn "*cmpdi_ccs_signhi_rl" [(set (reg CC_REGNUM) @@ -1002,7 +1032,7 @@ (label_ref (match_operand 3 "" "")) (pc))) (clobber (reg:CC CC_REGNUM))] - "TARGET_Z10" + "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH" { if (get_attr_length (insn) == 6) return which_alternative ? @@ -1030,7 +1060,7 @@ (label_ref (match_operand 3 "" "")) (pc))) (clobber (reg:CC CC_REGNUM))] - "TARGET_Z10" + "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH" { if (get_attr_length (insn) == 6) return which_alternative ? @@ -1060,7 +1090,7 @@ (pc) (label_ref (match_operand 3 "" "")))) (clobber (reg:CC CC_REGNUM))] - "TARGET_Z10" + "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH" { if (get_attr_length (insn) == 6) return which_alternative ? @@ -1088,7 +1118,7 @@ (pc) (label_ref (match_operand 3 "" "")))) (clobber (reg:CC CC_REGNUM))] - "TARGET_Z10" + "TARGET_Z10 && !TARGET_AVOID_CMP_AND_BRANCH" { if (get_attr_length (insn) == 6) return which_alternative ? @@ -1928,10 +1958,11 @@ "") (define_insn "*mov_64" - [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,o, d,QS, d,o") - (match_operand:TD_TF 1 "general_operand" " f,o,f,QS, d,dRT,d"))] + [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o, d,QS, d,o") + (match_operand:TD_TF 1 "general_operand" " G,f,o,f,QS, d,dRT,d"))] "TARGET_ZARCH" "@ + lzxr\t%0 lxr\t%0,%1 # # @@ -1939,19 +1970,22 @@ stmg\t%1,%N1,%S0 # #" - [(set_attr "op_type" "RRE,*,*,RSY,RSY,*,*") - (set_attr "type" "fsimptf,*,*,lm,stm,*,*")]) + [(set_attr "op_type" "RRE,RRE,*,*,RSY,RSY,*,*") + (set_attr "type" "fsimptf,fsimptf,*,*,lm,stm,*,*") + (set_attr "cpu_facility" "z196,*,*,*,*,*,*,*")]) (define_insn "*mov_31" - [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,o") - (match_operand:TD_TF 1 "general_operand" " f,o,f"))] + [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o") + (match_operand:TD_TF 1 "general_operand" " G,f,o,f"))] "!TARGET_ZARCH" "@ + lzxr\t%0 lxr\t%0,%1 # #" - [(set_attr "op_type" "RRE,*,*") - (set_attr "type" "fsimptf,*,*")]) + [(set_attr "op_type" "RRE,RRE,*,*") + (set_attr "type" "fsimptf,fsimptf,*,*") + (set_attr "cpu_facility" "z196,*,*,*")]) ; TFmode in GPRs splitters @@ -2042,11 +2076,12 @@ (define_insn "*mov_64dfp" [(set (match_operand:DD_DF 0 "nonimmediate_operand" - "=f,f,d,f,f,R,T,d,d, d,RT") + "=f,f,f,d,f,f,R,T,d,d, d,RT") (match_operand:DD_DF 1 "general_operand" - " f,d,f,R,T,f,f,G,d,RT, d"))] + " G,f,d,f,R,T,f,f,G,d,RT, d"))] "TARGET_DFP" "@ + lzdr\t%0 ldr\t%0,%1 ldgr\t%0,%1 lgdr\t%0,%1 @@ -2058,17 +2093,18 @@ lgr\t%0,%1 lg\t%0,%1 stg\t%1,%0" - [(set_attr "op_type" "RR,RRE,RRE,RX,RXY,RX,RXY,RI,RRE,RXY,RXY") - (set_attr "type" "floaddf,floaddf,floaddf,floaddf,floaddf, + [(set_attr "op_type" "RRE,RR,RRE,RRE,RX,RXY,RX,RXY,RI,RRE,RXY,RXY") + (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,floaddf,floaddf, fstoredf,fstoredf,*,lr,load,store") - (set_attr "z10prop" "*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_rec") -]) + (set_attr "z10prop" "*,*,*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_rec") + (set_attr "cpu_facility" "z196,*,*,*,*,*,*,*,*,*,*,*")]) (define_insn "*mov_64" - [(set (match_operand:DD_DF 0 "nonimmediate_operand" "=f,f,f,R,T,d,d, d,RT") - (match_operand:DD_DF 1 "general_operand" "f,R,T,f,f,G,d,RT, d"))] + [(set (match_operand:DD_DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d, d,RT") + (match_operand:DD_DF 1 "general_operand" " G,f,R,T,f,f,G,d,RT, d"))] "TARGET_ZARCH" "@ + lzdr\t%0 ldr\t%0,%1 ld\t%0,%1 ldy\t%0,%1 @@ -2078,18 +2114,20 @@ lgr\t%0,%1 lg\t%0,%1 stg\t%1,%0" - [(set_attr "op_type" "RR,RX,RXY,RX,RXY,RI,RRE,RXY,RXY") - (set_attr "type" "fload,fload,fload, - fstore,fstore,*,lr,load,store") - (set_attr "z10prop" "*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_rec")]) + [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RI,RRE,RXY,RXY") + (set_attr "type" "fsimpdf,fload,fload,fload, + fstore,fstore,*,lr,load,store") + (set_attr "z10prop" "*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_rec") + (set_attr "cpu_facility" "z196,*,*,*,*,*,*,*,*,*")]) (define_insn "*mov_31" [(set (match_operand:DD_DF 0 "nonimmediate_operand" - "=f,f,f,R,T,d,d,Q,S, d,o") + "=f,f,f,f,R,T,d,d,Q,S, d,o") (match_operand:DD_DF 1 "general_operand" - " f,R,T,f,f,Q,S,d,d,dPRT,d"))] + " G,f,R,T,f,f,Q,S,d,d,dPRT,d"))] "!TARGET_ZARCH" "@ + lzdr\t%0 ldr\t%0,%1 ld\t%0,%1 ldy\t%0,%1 @@ -2101,9 +2139,10 @@ stmy\t%1,%N1,%S0 # #" - [(set_attr "op_type" "RR,RX,RXY,RX,RXY,RS,RSY,RS,RSY,*,*") - (set_attr "type" "fload,fload,fload, - fstore,fstore,lm,lm,stm,stm,*,*")]) + [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RS,RSY,RS,RSY,*,*") + (set_attr "type" "fsimpdf,fload,fload,fload, + fstore,fstore,lm,lm,stm,stm,*,*") + (set_attr "cpu_facility" "z196,*,*,*,*,*,*,*,*,*,*,*")]) (define_split [(set (match_operand:DD_DF 0 "nonimmediate_operand" "") @@ -2152,11 +2191,12 @@ (define_insn "mov" [(set (match_operand:SD_SF 0 "nonimmediate_operand" - "=f,f,f,R,T,d,d,d,d,R,T") + "=f,f,f,f,R,T,d,d,d,d,R,T") (match_operand:SD_SF 1 "general_operand" - " f,R,T,f,f,G,d,R,T,d,d"))] + " G,f,R,T,f,f,G,d,R,T,d,d"))] "" "@ + lzer\t%0 ler\t%0,%1 le\t%0,%1 ley\t%0,%1 @@ -2168,10 +2208,11 @@ ly\t%0,%1 st\t%1,%0 sty\t%1,%0" - [(set_attr "op_type" "RR,RX,RXY,RX,RXY,RI,RR,RX,RXY,RX,RXY") - (set_attr "type" "fload,fload,fload, - fstore,fstore,*,lr,load,load,store,store") - (set_attr "z10prop" "*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec")]) + [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RI,RR,RX,RXY,RX,RXY") + (set_attr "type" "fsimpsf,fload,fload,fload, + fstore,fstore,*,lr,load,load,store,store") + (set_attr "z10prop" "*,*,*,*,*,*,z10_fwd_A1,z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec") + (set_attr "cpu_facility" "z196,*,*,*,*,*,*,*,*,*,*,*")]) ; ; movcc instruction pattern @@ -2191,7 +2232,8 @@ ly\t%1,%0" [(set_attr "op_type" "RR,RI,RRE,RX,RXY,RX,RXY") (set_attr "type" "lr,*,*,store,store,load,load") - (set_attr "z10prop" "z10_fr_E1,z10_super,*,z10_rec,z10_rec,z10_fwd_A3,z10_fwd_A3")]) + (set_attr "z10prop" "z10_fr_E1,z10_super,*,z10_rec,z10_rec,z10_fwd_A3,z10_fwd_A3") + (set_attr "z196prop" "*,*,z196_ends,*,*,*,*")]) ; ; Block move (MVC) patterns. @@ -3846,100 +3888,141 @@ [(parallel [(set (match_operand:DI 0 "register_operand" "") (unsigned_fix:DI (match_operand:DD 1 "register_operand" ""))) - (clobber (match_scratch:TD 2 "=f"))])] + (unspec:DI [(const_int 5)] UNSPEC_ROUND) + (clobber (reg:CC CC_REGNUM))])] "TARGET_HARD_DFP" { - rtx label1 = gen_label_rtx (); - rtx label2 = gen_label_rtx (); - rtx temp = gen_reg_rtx (TDmode); - REAL_VALUE_TYPE cmp, sub; + if (!TARGET_Z196) + { + rtx label1 = gen_label_rtx (); + rtx label2 = gen_label_rtx (); + rtx temp = gen_reg_rtx (TDmode); + REAL_VALUE_TYPE cmp, sub; - decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */ - decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */ + decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */ + decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */ - /* 2^63 can't be represented as 64bit DFP number with full precision. The - solution is doing the check and the subtraction in TD mode and using a - TD -> DI convert afterwards. */ - emit_insn (gen_extendddtd2 (temp, operands[1])); - temp = force_reg (TDmode, temp); - emit_cmp_and_jump_insns (temp, - CONST_DOUBLE_FROM_REAL_VALUE (cmp, TDmode), - LT, NULL_RTX, VOIDmode, 0, label1); - emit_insn (gen_subtd3 (temp, temp, - CONST_DOUBLE_FROM_REAL_VALUE (sub, TDmode))); - emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp, GEN_INT (11))); - emit_jump (label2); + /* 2^63 can't be represented as 64bit DFP number with full precision. The + solution is doing the check and the subtraction in TD mode and using a + TD -> DI convert afterwards. */ + emit_insn (gen_extendddtd2 (temp, operands[1])); + temp = force_reg (TDmode, temp); + emit_cmp_and_jump_insns (temp, + CONST_DOUBLE_FROM_REAL_VALUE (cmp, TDmode), + LT, NULL_RTX, VOIDmode, 0, label1); + emit_insn (gen_subtd3 (temp, temp, + CONST_DOUBLE_FROM_REAL_VALUE (sub, TDmode))); + emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp, GEN_INT (11))); + emit_jump (label2); - emit_label (label1); - emit_insn (gen_fix_truncdddi2_dfp (operands[0], operands[1], GEN_INT (9))); - emit_label (label2); - DONE; + emit_label (label1); + emit_insn (gen_fix_truncdddi2_dfp (operands[0], operands[1], GEN_INT (9))); + emit_label (label2); + DONE; + } }) (define_expand "fixuns_trunctddi2" - [(set (match_operand:DI 0 "register_operand" "") - (unsigned_fix:DI (match_operand:TD 1 "register_operand" "")))] + [(parallel + [(set (match_operand:DI 0 "register_operand" "") + (unsigned_fix:DI (match_operand:TD 1 "register_operand" ""))) + (unspec:DI [(const_int 5)] UNSPEC_ROUND) + (clobber (reg:CC CC_REGNUM))])] + "TARGET_HARD_DFP" { - rtx label1 = gen_label_rtx (); - rtx label2 = gen_label_rtx (); - rtx temp = gen_reg_rtx (TDmode); - REAL_VALUE_TYPE cmp, sub; + if (!TARGET_Z196) + { + rtx label1 = gen_label_rtx (); + rtx label2 = gen_label_rtx (); + rtx temp = gen_reg_rtx (TDmode); + REAL_VALUE_TYPE cmp, sub; - operands[1] = force_reg (TDmode, operands[1]); - decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */ - decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */ + operands[1] = force_reg (TDmode, operands[1]); + decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */ + decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */ - emit_cmp_and_jump_insns (operands[1], - CONST_DOUBLE_FROM_REAL_VALUE (cmp, TDmode), - LT, NULL_RTX, VOIDmode, 0, label1); - emit_insn (gen_subtd3 (temp, operands[1], - CONST_DOUBLE_FROM_REAL_VALUE (sub, TDmode))); - emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp, GEN_INT (11))); - emit_jump (label2); + emit_cmp_and_jump_insns (operands[1], + CONST_DOUBLE_FROM_REAL_VALUE (cmp, TDmode), + LT, NULL_RTX, VOIDmode, 0, label1); + emit_insn (gen_subtd3 (temp, operands[1], + CONST_DOUBLE_FROM_REAL_VALUE (sub, TDmode))); + emit_insn (gen_fix_trunctddi2_dfp (operands[0], temp, GEN_INT (11))); + emit_jump (label2); - emit_label (label1); - emit_insn (gen_fix_trunctddi2_dfp (operands[0], operands[1], GEN_INT (9))); - emit_label (label2); - DONE; + emit_label (label1); + emit_insn (gen_fix_trunctddi2_dfp (operands[0], operands[1], GEN_INT (9))); + emit_label (label2); + DONE; + } }) ; -; fixuns_trunc(sf|df)(si|di)2 and fix_trunc(sf|df)(si|di)2 +; fixuns_trunc(sf|df|tf)(si|di)2 and fix_trunc(sf|df|tf)(si|di)2 ; instruction pattern(s). ; (define_expand "fixuns_trunc2" - [(set (match_operand:GPR 0 "register_operand" "") - (unsigned_fix:GPR (match_operand:BFP 1 "register_operand" "")))] + [(parallel + [(set (match_operand:GPR 0 "register_operand" "") + (unsigned_fix:GPR (match_operand:BFP 1 "register_operand" ""))) + (unspec:GPR [(const_int 5)] UNSPEC_ROUND) + (clobber (reg:CC CC_REGNUM))])] "TARGET_HARD_FLOAT" { - rtx label1 = gen_label_rtx (); - rtx label2 = gen_label_rtx (); - rtx temp = gen_reg_rtx (mode); - REAL_VALUE_TYPE cmp, sub; + if (!TARGET_Z196) + { + rtx label1 = gen_label_rtx (); + rtx label2 = gen_label_rtx (); + rtx temp = gen_reg_rtx (mode); + REAL_VALUE_TYPE cmp, sub; - operands[1] = force_reg (mode, operands[1]); - real_2expN (&cmp, GET_MODE_BITSIZE(mode) - 1, mode); - real_2expN (&sub, GET_MODE_BITSIZE(mode), mode); + operands[1] = force_reg (mode, operands[1]); + real_2expN (&cmp, GET_MODE_BITSIZE(mode) - 1, mode); + real_2expN (&sub, GET_MODE_BITSIZE(mode), mode); - emit_cmp_and_jump_insns (operands[1], - CONST_DOUBLE_FROM_REAL_VALUE (cmp, mode), - LT, NULL_RTX, VOIDmode, 0, label1); - emit_insn (gen_sub3 (temp, operands[1], - CONST_DOUBLE_FROM_REAL_VALUE (sub, mode))); - emit_insn (gen_fix_trunc2_bfp (operands[0], temp, - GEN_INT (7))); - emit_jump (label2); + emit_cmp_and_jump_insns (operands[1], + CONST_DOUBLE_FROM_REAL_VALUE (cmp, mode), + LT, NULL_RTX, VOIDmode, 0, label1); + emit_insn (gen_sub3 (temp, operands[1], + CONST_DOUBLE_FROM_REAL_VALUE (sub, mode))); + emit_insn (gen_fix_trunc2_bfp (operands[0], temp, + GEN_INT (7))); + emit_jump (label2); - emit_label (label1); - emit_insn (gen_fix_trunc2_bfp (operands[0], - operands[1], GEN_INT (5))); - emit_label (label2); - DONE; + emit_label (label1); + emit_insn (gen_fix_trunc2_bfp (operands[0], + operands[1], GEN_INT (5))); + emit_label (label2); + DONE; + } }) +; fixuns_trunc(td|dd)si2 expander +(define_expand "fixuns_truncsi2" + [(parallel + [(set (match_operand:SI 0 "register_operand" "") + (unsigned_fix:SI (match_operand:DFP 1 "register_operand" ""))) + (unspec:SI [(const_int 5)] UNSPEC_ROUND) + (clobber (reg:CC CC_REGNUM))])] + "TARGET_Z196 && TARGET_HARD_FLOAT" + "") + +; fixuns_trunc(tf|df|sf|td|dd)(di|si)2 instruction patterns. + +; clfebr, clfdbr, clfxbr, clgebr, clgdbr, clgxbr +; clfdtr, clfxtr, clgdtr, clgxtr +(define_insn "*fixuns_trunc2_z196" + [(set (match_operand:GPR 0 "register_operand" "=r") + (unsigned_fix:GPR (match_operand:FP 1 "register_operand" "f"))) + (unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND) + (clobber (reg:CC CC_REGNUM))] + "TARGET_Z196" + "clr\t%0,%h2,%1,0" + [(set_attr "op_type" "RRF") + (set_attr "type" "ftoi")]) + (define_expand "fix_trunc2" [(set (match_operand:GPR 0 "register_operand" "") (fix:GPR (match_operand:DSF 1 "register_operand" "")))] @@ -4024,6 +4107,28 @@ [(set_attr "op_type" "RRE") (set_attr "type" "itof" )]) +; cxftr, cdftr +(define_insn "floatsi2" + [(set (match_operand:DFP 0 "register_operand" "=f") + (float:DFP (match_operand:SI 1 "register_operand" "d")))] + "TARGET_Z196 && TARGET_HARD_FLOAT" + "cftr\t%0,0,%1,0" + [(set_attr "op_type" "RRE") + (set_attr "type" "itof" )]) + +; +; floatuns(si|di)(tf|df|sf|td|dd)2 instruction pattern(s). +; + +; cxlgbr, cdlgbr, celgbr, cxlgtr, cdlgtr +; cxlfbr, cdlfbr, celfbr, cxlftr, cdlftr +(define_insn "floatuns2" + [(set (match_operand:FP 0 "register_operand" "=f") + (unsigned_float:FP (match_operand:GPR 1 "register_operand" "d")))] + "TARGET_Z196 && TARGET_HARD_FLOAT" + "clr\t%0,0,%1,0" + [(set_attr "op_type" "RRE") + (set_attr "type" "itof" )]) ; ; truncdfsf2 instruction pattern(s). @@ -4294,7 +4399,8 @@ "@ agfr\t%0,%2 agf\t%0,%2" - [(set_attr "op_type" "RRE,RXY")]) + [(set_attr "op_type" "RRE,RXY") + (set_attr "z196prop" "z196_cracked,z196_cracked")]) (define_insn "*adddi3_zero_cc" [(set (reg CC_REGNUM) @@ -4414,178 +4520,178 @@ "@ ah\t%0,%2 ahy\t%0,%2" - [(set_attr "op_type" "RX,RXY")]) + [(set_attr "op_type" "RX,RXY") + (set_attr "z196prop" "z196_cracked,z196_cracked")]) ; ; add(di|si)3 instruction pattern(s). ; -; ar, ahi, alfi, slfi, a, ay, agr, aghi, algfi, slgfi, ag, asi, agsi +; ark, agrk, ar, ahi, ahik, aghik, alfi, slfi, a, ay, agr, aghi, algfi, slgfi, ag, asi, agsi (define_insn "*add3" - [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d,d,d,QS") - (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0,0,0") - (match_operand:GPR 2 "general_operand" "d,K,Op,On,R,T,C") ) ) + [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d, d, d,d,d,QS") + (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,d, 0, 0,0,0, 0") + (match_operand:GPR 2 "general_operand" " d,d,K,K,Op,On,R,T, C") ) ) (clobber (reg:CC CC_REGNUM))] "" "@ ar\t%0,%2 + ark\t%0,%1,%2 ahi\t%0,%h2 + ahik\t%0,%1,%h2 alfi\t%0,%2 slfi\t%0,%n2 a\t%0,%2 a\t%0,%2 asi\t%0,%c2" - [(set_attr "op_type" "RR,RI,RIL,RIL,RX,RXY,SIY") - (set_attr "cpu_facility" "*,*,extimm,extimm,*,*,z10") - (set_attr "z10prop" "z10_super_E1, - z10_super_E1, - z10_super_E1, - z10_super_E1, - z10_super_E1, - z10_super_E1, - z10_super_E1")]) + [(set_attr "op_type" "RR,RRF,RI,RIE,RIL,RIL,RX,RXY,SIY") + (set_attr "cpu_facility" "*,z196,*,z196,extimm,extimm,*,*,z10") + (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,z10_super_E1,z10_super_E1, + z10_super_E1,z10_super_E1,z10_super_E1")]) -; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi +; alr, alfi, slfi, al, aly, alrk, alhsik, algr, algfi, slgfi, alg, alsi, algsi, algrk, alghsik (define_insn "*add3_carry1_cc" [(set (reg CC_REGNUM) - (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0,0") - (match_operand:GPR 2 "general_operand" "d,Op,On,R,T,C")) + (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0,0") + (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T,C")) (match_dup 1))) - (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d,d,d") + (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,d") (plus:GPR (match_dup 1) (match_dup 2)))] "s390_match_ccmode (insn, CCL1mode)" "@ alr\t%0,%2 + alrk\t%0,%1,%2 alfi\t%0,%2 slfi\t%0,%n2 + alhsik\t%0,%1,%h2 al\t%0,%2 al\t%0,%2 alsi\t%0,%c2" - [(set_attr "op_type" "RR,RIL,RIL,RX,RXY,SIY") - (set_attr "cpu_facility" "*,extimm,extimm,*,*,z10") - (set_attr "z10prop" "z10_super_E1, - z10_super_E1, - z10_super_E1, - z10_super_E1, - z10_super_E1, - z10_super_E1")]) + [(set_attr "op_type" "RR,RRF,RIL,RIL,RIE,RX,RXY,SIY") + (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,*,z10") + (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,*, + z10_super_E1,z10_super_E1,z10_super_E1")]) -; alr, al, aly, algr, alg +; alr, al, aly, algr, alg, alrk, algrk (define_insn "*add3_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")) + (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0") + (match_operand:GPR 2 "general_operand" "d,d,R,T")) (match_dup 1))) - (clobber (match_scratch:GPR 0 "=d,d,d"))] + (clobber (match_scratch:GPR 0 "=d,d,d,d"))] "s390_match_ccmode (insn, CCL1mode)" "@ alr\t%0,%2 + alrk\t%0,%1,%2 al\t%0,%2 al\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY") - (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")]) + [(set_attr "op_type" "RR,RRF,RX,RXY") + (set_attr "cpu_facility" "*,z196,*,*") + (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")]) -; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi +; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi, alrk, algrk, alhsik, alghsik (define_insn "*add3_carry2_cc" [(set (reg CC_REGNUM) - (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0,0") - (match_operand:GPR 2 "general_operand" "d,Op,On,R,T,C")) + (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0, 0") + (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T, C")) (match_dup 2))) - (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d,d,RS") + (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,RS") (plus:GPR (match_dup 1) (match_dup 2)))] "s390_match_ccmode (insn, CCL1mode)" "@ alr\t%0,%2 + alrk\t%0,%1,%2 alfi\t%0,%2 slfi\t%0,%n2 + alhsik\t%0,%1,%h2 al\t%0,%2 al\t%0,%2 alsi\t%0,%c2" - [(set_attr "op_type" "RR,RIL,RIL,RX,RXY,SIY") - (set_attr "cpu_facility" "*,extimm,extimm,*,*,z10") - (set_attr "z10prop" "z10_super_E1, - z10_super_E1, - z10_super_E1, - z10_super_E1, - z10_super_E1, - z10_super_E1")]) + [(set_attr "op_type" "RR,RRF,RIL,RIL,RIE,RX,RXY,SIY") + (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,*,z10") + (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1,*, + z10_super_E1,z10_super_E1,z10_super_E1")]) -; alr, al, aly, algr, alg +; alr, al, aly, algr, alg, alrk, algrk (define_insn "*add3_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")) + (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0") + (match_operand:GPR 2 "general_operand" "d,d,R,T")) (match_dup 2))) - (clobber (match_scratch:GPR 0 "=d,d,d"))] + (clobber (match_scratch:GPR 0 "=d,d,d,d"))] "s390_match_ccmode (insn, CCL1mode)" "@ alr\t%0,%2 + alrk\t%0,%1,%2 al\t%0,%2 al\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY") - (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")]) + [(set_attr "op_type" "RR,RRF,RX,RXY") + (set_attr "cpu_facility" "*,z196,*,*") + (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")]) -; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi +; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi, alrk, algrk, alhsik, alghsik (define_insn "*add3_cc" [(set (reg CC_REGNUM) - (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0,0") - (match_operand:GPR 2 "general_operand" "d,Op,On,R,T,C")) + (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d, 0, 0,d,0,0, 0") + (match_operand:GPR 2 "general_operand" " d,d,Op,On,K,R,T, C")) (const_int 0))) - (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d,d,RS") + (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,d,d,d,RS") (plus:GPR (match_dup 1) (match_dup 2)))] "s390_match_ccmode (insn, CCLmode)" "@ alr\t%0,%2 + alrk\t%0,%1,%2 alfi\t%0,%2 slfi\t%0,%n2 + alhsik\t%0,%1,%h2 al\t%0,%2 al\t%0,%2 alsi\t%0,%c2" - [(set_attr "op_type" "RR,RIL,RIL,RX,RXY,SIY") - (set_attr "cpu_facility" "*,extimm,extimm,*,*,z10") - (set_attr "z10prop" "z10_super_E1, - z10_super_E1, - z10_super_E1, - z10_super_E1, - z10_super_E1, - z10_super_E1")]) + [(set_attr "op_type" "RR,RRF,RIL,RIL,RIE,RX,RXY,SIY") + (set_attr "cpu_facility" "*,z196,extimm,extimm,z196,*,*,z10") + (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1, + *,z10_super_E1,z10_super_E1,z10_super_E1")]) -; alr, al, aly, algr, alg +; alr, al, aly, algr, alg, alrk, algrk (define_insn "*add3_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")) + (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0") + (match_operand:GPR 2 "general_operand" "d,d,R,T")) (const_int 0))) - (clobber (match_scratch:GPR 0 "=d,d,d"))] + (clobber (match_scratch:GPR 0 "=d,d,d,d"))] "s390_match_ccmode (insn, CCLmode)" "@ alr\t%0,%2 + alrk\t%0,%1,%2 al\t%0,%2 al\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY") - (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")]) + [(set_attr "op_type" "RR,RRF,RX,RXY") + (set_attr "cpu_facility" "*,z196,*,*") + (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")]) -; alr, al, aly, algr, alg +; alr, al, aly, algr, alg, alrk, algrk (define_insn "*add3_cconly2" [(set (reg CC_REGNUM) - (compare (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0") - (neg:GPR (match_operand:GPR 2 "general_operand" "d,R,T")))) - (clobber (match_scratch:GPR 0 "=d,d,d"))] + (compare (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,0") + (neg:GPR (match_operand:GPR 2 "general_operand" "d,d,R,T")))) + (clobber (match_scratch:GPR 0 "=d,d,d,d"))] "s390_match_ccmode(insn, CCLmode)" "@ alr\t%0,%2 + alrk\t%0,%1,%2 al\t%0,%2 al\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY") - (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")]) + [(set_attr "op_type" "RR,RRF,RX,RXY") + (set_attr "cpu_facility" "*,z196,*,*") + (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")]) ; ahi, afi, aghi, agfi, asi, agsi (define_insn "*add3_imm_cc" [(set (reg CC_REGNUM) - (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0,0") - (match_operand:GPR 2 "const_int_operand" "K,Os,C")) + (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" " 0, d,0, 0") + (match_operand:GPR 2 "const_int_operand" " K, K,Os, C")) (const_int 0))) - (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,QS") + (set (match_operand:GPR 0 "nonimmediate_operand" "=d, d,d,QS") (plus:GPR (match_dup 1) (match_dup 2)))] "s390_match_ccmode (insn, CCAmode) && (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\") @@ -4594,11 +4700,12 @@ && INTVAL (operands[2]) != -((HOST_WIDE_INT)1 << (GET_MODE_BITSIZE(mode) - 1))" "@ ahi\t%0,%h2 + ahik\t%0,%1,%h2 afi\t%0,%2 asi\t%0,%c2" - [(set_attr "op_type" "RI,RIL,SIY") - (set_attr "cpu_facility" "*,extimm,z10") - (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")]) + [(set_attr "op_type" "RI,RIE,RIL,SIY") + (set_attr "cpu_facility" "*,z196,extimm,z10") + (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")]) ; ; add(tf|df|sf|td|dd)3 instruction pattern(s). @@ -4702,7 +4809,8 @@ sgfr\t%0,%2 sgf\t%0,%2" [(set_attr "op_type" "RRE,RXY") - (set_attr "z10prop" "z10_c,*")]) + (set_attr "z10prop" "z10_c,*") + (set_attr "z196prop" "z196_cracked")]) (define_insn "*subdi3_zero_cc" [(set (reg CC_REGNUM) @@ -4821,117 +4929,132 @@ "@ sh\t%0,%2 shy\t%0,%2" - [(set_attr "op_type" "RX,RXY")]) + [(set_attr "op_type" "RX,RXY") + (set_attr "z196prop" "z196_cracked,z196_cracked")]) ; ; sub(di|si)3 instruction pattern(s). ; -; sr, s, sy, sgr, sg +; sr, s, sy, sgr, sg, srk, sgrk (define_insn "*sub3" - [(set (match_operand:GPR 0 "register_operand" "=d,d,d") - (minus:GPR (match_operand:GPR 1 "register_operand" "0,0,0") - (match_operand:GPR 2 "general_operand" "d,R,T") ) ) + [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d") + (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0") + (match_operand:GPR 2 "general_operand" "d,d,R,T") ) ) (clobber (reg:CC CC_REGNUM))] "" "@ sr\t%0,%2 + srk\t%0,%1,%2 s\t%0,%2 s\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY") - (set_attr "z10prop" "z10_super_c_E1,z10_super_E1,z10_super_E1")]) + [(set_attr "op_type" "RR,RRF,RX,RXY") + (set_attr "cpu_facility" "*,z196,*,*") + (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")]) -; slr, sl, sly, slgr, slg +; slr, sl, sly, slgr, slg, slrk, slgrk (define_insn "*sub3_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")) + (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0") + (match_operand:GPR 2 "general_operand" "d,d,R,T")) (match_dup 1))) - (set (match_operand:GPR 0 "register_operand" "=d,d,d") + (set (match_operand:GPR 0 "register_operand" "=d,d,d,d") (minus:GPR (match_dup 1) (match_dup 2)))] "s390_match_ccmode (insn, CCL2mode)" "@ slr\t%0,%2 + slrk\t%0,%1,%2 sl\t%0,%2 sl\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY") - (set_attr "z10prop" "z10_super_c_E1,z10_super_E1,z10_super_E1")]) + [(set_attr "op_type" "RR,RRF,RX,RXY") + (set_attr "cpu_facility" "*,z196,*,*") + (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")]) -; slr, sl, sly, slgr, slg +; slr, sl, sly, slgr, slg, slrk, slgrk (define_insn "*sub3_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")) + (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0") + (match_operand:GPR 2 "general_operand" "d,d,R,T")) (match_dup 1))) - (clobber (match_scratch:GPR 0 "=d,d,d"))] + (clobber (match_scratch:GPR 0 "=d,d,d,d"))] "s390_match_ccmode (insn, CCL2mode)" "@ slr\t%0,%2 + slrk\t%0,%1,%2 sl\t%0,%2 sl\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY") - (set_attr "z10prop" "z10_super_c_E1,z10_super_E1,z10_super_E1")]) + [(set_attr "op_type" "RR,RRF,RX,RXY") + (set_attr "cpu_facility" "*,z196,*,*") + (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")]) -; slr, sl, sly, slgr, slg +; slr, sl, sly, slgr, slg, slrk, slgrk (define_insn "*sub3_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")) + (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0") + (match_operand:GPR 2 "general_operand" "d,d,R,T")) (const_int 0))) - (set (match_operand:GPR 0 "register_operand" "=d,d,d") + (set (match_operand:GPR 0 "register_operand" "=d,d,d,d") (minus:GPR (match_dup 1) (match_dup 2)))] "s390_match_ccmode (insn, CCLmode)" "@ slr\t%0,%2 + slrk\t%0,%1,%2 sl\t%0,%2 sl\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY") - (set_attr "z10prop" "z10_super_c_E1,z10_super_E1,z10_super_E1")]) + [(set_attr "op_type" "RR,RRF,RX,RXY") + (set_attr "cpu_facility" "*,z196,*,*") + (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")]) -; slr, sl, sly, slgr, slg +; slr, sl, sly, slgr, slg, slrk, slgrk (define_insn "*sub3_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") + (compare (match_operand:GPR 1 "register_operand" "0,d,0,0") + (match_operand:GPR 2 "general_operand" "d,d,R,T"))) + (set (match_operand:GPR 0 "register_operand" "=d,d,d,d") (minus:GPR (match_dup 1) (match_dup 2)))] "s390_match_ccmode (insn, CCL3mode)" "@ slr\t%0,%2 + slrk\t%0,%1,%2 sl\t%0,%2 sl\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY") - (set_attr "z10prop" "z10_super_c_E1,z10_super_E1,z10_super_E1")]) + [(set_attr "op_type" "RR,RRF,RX,RXY") + (set_attr "cpu_facility" "*,z196,*,*") + (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")]) -; slr, sl, sly, slgr, slg +; slr, sl, sly, slgr, slg, slrk, slgrk (define_insn "*sub3_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")) + (compare (minus:GPR (match_operand:GPR 1 "register_operand" "0,d,0,0") + (match_operand:GPR 2 "general_operand" "d,d,R,T")) (const_int 0))) - (clobber (match_scratch:GPR 0 "=d,d,d"))] + (clobber (match_scratch:GPR 0 "=d,d,d,d"))] "s390_match_ccmode (insn, CCLmode)" "@ slr\t%0,%2 + slrk\t%0,%1,%2 sl\t%0,%2 sl\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY") - (set_attr "z10prop" "z10_super_c_E1,z10_super_E1,z10_super_E1")]) + [(set_attr "op_type" "RR,RRF,RX,RXY") + (set_attr "cpu_facility" "*,z196,*,*") + (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")]) -; slr, sl, sly, slgr, slg +; slr, sl, sly, slgr, slg, slrk, slgrk (define_insn "*sub3_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"))] + (compare (match_operand:GPR 1 "register_operand" "0,d,0,0") + (match_operand:GPR 2 "general_operand" "d,d,R,T"))) + (clobber (match_scratch:GPR 0 "=d,d,d,d"))] "s390_match_ccmode (insn, CCL3mode)" "@ slr\t%0,%2 + slrk\t%0,%1,%2 sl\t%0,%2 sl\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY") - (set_attr "z10prop" "z10_super_c_E1,z10_super_E1,z10_super_E1")]) + [(set_attr "op_type" "RR,RRF,RX,RXY") + (set_attr "cpu_facility" "*,z196,*,*") + (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")]) ; @@ -5008,7 +5131,8 @@ "@ alcr\t%0,%2 alc\t%0,%2" - [(set_attr "op_type" "RRE,RXY")]) + [(set_attr "op_type" "RRE,RXY") + (set_attr "z196prop" "z196_alone,z196_alone")]) ; alcr, alc, alcgr, alcg (define_insn "*add3_alc_carry1_cconly" @@ -5023,7 +5147,8 @@ "@ alcr\t%0,%2 alc\t%0,%2" - [(set_attr "op_type" "RRE,RXY")]) + [(set_attr "op_type" "RRE,RXY") + (set_attr "z196prop" "z196_alone,z196_alone")]) ; op1 + op2 + c < op2 @@ -5200,6 +5325,52 @@ (clobber (reg:CC CC_REGNUM))])]) +;; +;; - Conditional move instructions (introduced with z196) +;; + +(define_expand "movcc" + [(set (match_operand:GPR 0 "nonimmediate_operand" "") + (if_then_else:GPR (match_operand 1 "comparison_operator" "") + (match_operand:GPR 2 "nonimmediate_operand" "") + (match_operand:GPR 3 "nonimmediate_operand" "")))] + "TARGET_Z196" + "operands[1] = s390_emit_compare (GET_CODE (operands[1]), + XEXP (operands[1], 0), XEXP (operands[1], 1));") + +; locr, loc, stoc, locgr, lgoc, stgoc +(define_insn_and_split "*movcc" + [(set (match_operand:GPR 0 "nonimmediate_operand" "=d,d, d, d,QS,QS,&d") + (if_then_else:GPR + (match_operator 1 "s390_comparison" + [(match_operand 2 "cc_reg_operand" " c,c, c, c, c, c, c") + (const_int 0)]) + (match_operand:GPR 3 "nonimmediate_operand" " d,0,QS, 0, d, 0,QS") + (match_operand:GPR 4 "nonimmediate_operand" " 0,d, 0,QS, 0, d,QS")))] + "TARGET_Z196" + "@ + locr%C1\t%0,%3 + locr%D1\t%0,%4 + loc%C1\t%0,%3 + loc%D1\t%0,%4 + stoc%C1\t%3,%0 + stoc%D1\t%4,%0 + #" + "&& reload_completed + && MEM_P (operands[3]) && MEM_P (operands[4])" + [(set (match_dup 0) + (if_then_else:GPR + (match_op_dup 1 [(match_dup 2) (const_int 0)]) + (match_dup 3) + (match_dup 0))) + (set (match_dup 0) + (if_then_else:GPR + (match_op_dup 1 [(match_dup 2) (const_int 0)]) + (match_dup 0) + (match_dup 4)))] + "" + [(set_attr "op_type" "RRF,RRF,RSY,RSY,RSY,RSY,*")]) + ;; ;;- Multiply instructions. ;; @@ -5327,7 +5498,7 @@ mabr\t%0,%1,%2 mab\t%0,%1,%2" [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fmul")]) + (set_attr "type" "fmadd")]) ; msxbr, msdbr, msebr, msxb, msdb, mseb (define_insn "*fmsub" @@ -5340,7 +5511,7 @@ msbr\t%0,%1,%2 msb\t%0,%1,%2" [(set_attr "op_type" "RRE,RXE") - (set_attr "type" "fmul")]) + (set_attr "type" "fmadd")]) ;; ;;- Divide and modulo instructions. @@ -5795,39 +5966,44 @@ (define_insn "*anddi3_cc" [(set (reg CC_REGNUM) - (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") - (match_operand:DI 2 "general_operand" "d,RT")) + (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d, 0") + (match_operand:DI 2 "general_operand" " d,d,RT")) (const_int 0))) - (set (match_operand:DI 0 "register_operand" "=d,d") + (set (match_operand:DI 0 "register_operand" "=d,d, d") (and:DI (match_dup 1) (match_dup 2)))] "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH" "@ ngr\t%0,%2 + ngrk\t%0,%1,%2 ng\t%0,%2" - [(set_attr "op_type" "RRE,RXY") - (set_attr "z10prop" "z10_super_E1,z10_super_E1")]) + [(set_attr "op_type" "RRE,RRF,RXY") + (set_attr "cpu_facility" "*,z196,*") + (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")]) (define_insn "*anddi3_cconly" [(set (reg CC_REGNUM) - (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") - (match_operand:DI 2 "general_operand" "d,RT")) + (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d, 0") + (match_operand:DI 2 "general_operand" " d,d,RT")) (const_int 0))) - (clobber (match_scratch:DI 0 "=d,d"))] + (clobber (match_scratch:DI 0 "=d,d, d"))] "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH /* Do not steal TM patterns. */ && s390_single_part (operands[2], DImode, HImode, 0) < 0" "@ ngr\t%0,%2 + ngrk\t%0,%1,%2 ng\t%0,%2" - [(set_attr "op_type" "RRE,RXY") - (set_attr "z10prop" "z10_super_E1, z10_super_E1")]) + [(set_attr "op_type" "RRE,RRF,RXY") + (set_attr "cpu_facility" "*,z196,*") + (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")]) (define_insn "*anddi3" - [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,d,d,AQ,Q") + [(set (match_operand:DI 0 "nonimmediate_operand" + "=d,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") + "%d,o, 0, 0, 0, 0, 0, 0,0,d, 0, 0,0") (match_operand:DI 2 "general_operand" - "M,M,N0HDF,N1HDF,N2HDF,N3HDF,N0SDF,N1SDF,d,RT,NxQDF,Q"))) + "M, M,N0HDF,N1HDF,N2HDF,N3HDF,N0SDF,N1SDF,d,d,RT,NxQDF,Q"))) (clobber (reg:CC CC_REGNUM))] "TARGET_ZARCH && s390_logical_operator_ok_p (operands)" "@ @@ -5840,11 +6016,12 @@ nihf\t%0,%m2 nilf\t%0,%m2 ngr\t%0,%2 + ngrk\t%0,%1,%2 ng\t%0,%2 # #" - [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RIL,RIL,RRE,RXY,SI,SS") - (set_attr "cpu_facility" "*,*,*,*,*,*,extimm,extimm,*,*,*,*") + [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,SI,SS") + (set_attr "cpu_facility" "*,*,*,*,*,*,extimm,extimm,*,z196,*,*,*") (set_attr "z10prop" "*, *, z10_super_E1, @@ -5854,6 +6031,7 @@ z10_super_E1, z10_super_E1, z10_super_E1, + *, z10_super_E1, *, *")]) @@ -5875,43 +6053,49 @@ (define_insn "*andsi3_cc" [(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")) + (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0") + (match_operand:SI 2 "general_operand" "Os,d,d,R,T")) (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=d,d,d,d") + (set (match_operand:SI 0 "register_operand" "=d,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 + nrk\t%0,%1,%2 n\t%0,%2 ny\t%0,%2" - [(set_attr "op_type" "RIL,RR,RX,RXY") - (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,z10_super_E1")]) + [(set_attr "op_type" "RIL,RR,RRF,RX,RXY") + (set_attr "cpu_facility" "*,*,z196,*,*") + (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")]) (define_insn "*andsi3_cconly" [(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")) + (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0") + (match_operand:SI 2 "general_operand" "Os,d,d,R,T")) (const_int 0))) - (clobber (match_scratch:SI 0 "=d,d,d,d"))] + (clobber (match_scratch:SI 0 "=d,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 + nrk\t%0,%1,%2 n\t%0,%2 ny\t%0,%2" - [(set_attr "op_type" "RIL,RR,RX,RXY") - (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,z10_super_E1")]) + [(set_attr "op_type" "RIL,RR,RRF,RX,RXY") + (set_attr "cpu_facility" "*,*,z196,*,*") + (set_attr "z10prop" "z10_super_E1,z10_super_E1,*, + z10_super_E1,z10_super_E1")]) (define_insn "*andsi3_zarch" - [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,AQ,Q") + [(set (match_operand:SI 0 "nonimmediate_operand" + "=d,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") + "%d,o, 0, 0, 0,0,d,0,0, 0,0") (match_operand:SI 2 "general_operand" - "M,M,N0HSF,N1HSF,Os,d,R,T,NxQSF,Q"))) + " M,M,N0HSF,N1HSF,Os,d,d,R,T,NxQSF,Q"))) (clobber (reg:CC CC_REGNUM))] "TARGET_ZARCH && s390_logical_operator_ok_p (operands)" "@ @@ -5921,26 +6105,29 @@ nill\t%0,%j2 nilf\t%0,%o2 nr\t%0,%2 + nrk\t%0,%1,%2 n\t%0,%2 ny\t%0,%2 # #" - [(set_attr "op_type" "RRE,RXE,RI,RI,RIL,RR,RX,RXY,SI,SS") + [(set_attr "op_type" "RRE,RXE,RI,RI,RIL,RR,RRF,RX,RXY,SI,SS") + (set_attr "cpu_facility" "*,*,*,*,*,*,z196,*,*,*,*") (set_attr "z10prop" "*, *, z10_super_E1, z10_super_E1, z10_super_E1, z10_super_E1, + *, z10_super_E1, z10_super_E1, *, *")]) (define_insn "*andsi3_esa" - [(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"))) + [(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)" "@ @@ -5967,18 +6154,20 @@ ; (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"))) + [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q") + (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0, 0,0") + (match_operand:HI 2 "general_operand" " d,d,n,NxQHF,Q"))) (clobber (reg:CC CC_REGNUM))] "TARGET_ZARCH && s390_logical_operator_ok_p (operands)" "@ nr\t%0,%2 + nrk\t%0,%1,%2 nill\t%0,%x2 # #" - [(set_attr "op_type" "RR,RI,SI,SS") - (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*") + [(set_attr "op_type" "RR,RRF,RI,SI,SS") + (set_attr "cpu_facility" "*,z196,*,*,*") + (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*") ]) (define_insn "*andhi3_esa" @@ -6010,19 +6199,21 @@ ; (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"))) + [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q") + (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0") + (match_operand:QI 2 "general_operand" " d,d,n,n,n,Q"))) (clobber (reg:CC CC_REGNUM))] "TARGET_ZARCH && s390_logical_operator_ok_p (operands)" "@ nr\t%0,%2 + nrk\t%0,%1,%2 nill\t%0,%b2 ni\t%S0,%b2 niy\t%S0,%b2 #" - [(set_attr "op_type" "RR,RI,SI,SIY,SS") - (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super,z10_super,*")]) + [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS") + (set_attr "cpu_facility" "*,z196,*,*,*,*") + (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super,z10_super,*")]) (define_insn "*andqi3_esa" [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q") @@ -6049,7 +6240,8 @@ (clobber (reg:CC CC_REGNUM))] "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256" "nc\t%O0(%2,%R0),%S1" - [(set_attr "op_type" "SS")]) + [(set_attr "op_type" "SS") + (set_attr "z196prop" "z196_cracked")]) (define_split [(set (match_operand 0 "memory_operand" "") @@ -6114,36 +6306,42 @@ (define_insn "*iordi3_cc" [(set (reg CC_REGNUM) - (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") - (match_operand:DI 2 "general_operand" "d,RT")) + (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d, 0") + (match_operand:DI 2 "general_operand" " d,d,RT")) (const_int 0))) - (set (match_operand:DI 0 "register_operand" "=d,d") + (set (match_operand:DI 0 "register_operand" "=d,d, d") (ior:DI (match_dup 1) (match_dup 2)))] "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH" "@ ogr\t%0,%2 + ogrk\t%0,%1,%2 og\t%0,%2" - [(set_attr "op_type" "RRE,RXY") - (set_attr "z10prop" "z10_super_E1,z10_super_E1")]) + [(set_attr "op_type" "RRE,RRF,RXY") + (set_attr "cpu_facility" "*,z196,*") + (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")]) (define_insn "*iordi3_cconly" [(set (reg CC_REGNUM) - (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") - (match_operand:DI 2 "general_operand" "d,RT")) + (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0") + (match_operand:DI 2 "general_operand" " d,d,RT")) (const_int 0))) - (clobber (match_scratch:DI 0 "=d,d"))] + (clobber (match_scratch:DI 0 "=d,d,d"))] "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH" "@ ogr\t%0,%2 + ogrk\t%0,%1,%2 og\t%0,%2" - [(set_attr "op_type" "RRE,RXY") - (set_attr "z10prop" "z10_super_E1,z10_super_E1")]) + [(set_attr "op_type" "RRE,RRF,RXY") + (set_attr "cpu_facility" "*,z196,*") + (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")]) (define_insn "*iordi3" - [(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") + [(set (match_operand:DI 0 "nonimmediate_operand" + "=d, 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,d, 0, 0,0") (match_operand:DI 2 "general_operand" - "N0HD0,N1HD0,N2HD0,N3HD0,N0SD0,N1SD0,d,RT,NxQD0,Q"))) + "N0HD0,N1HD0,N2HD0,N3HD0,N0SD0,N1SD0,d,d,RT,NxQD0,Q"))) (clobber (reg:CC CC_REGNUM))] "TARGET_ZARCH && s390_logical_operator_ok_p (operands)" "@ @@ -6154,11 +6352,12 @@ oihf\t%0,%k2 oilf\t%0,%k2 ogr\t%0,%2 + ogrk\t%0,%1,%2 og\t%0,%2 # #" - [(set_attr "op_type" "RI,RI,RI,RI,RIL,RIL,RRE,RXY,SI,SS") - (set_attr "cpu_facility" "*,*,*,*,extimm,extimm,*,*,*,*") + [(set_attr "op_type" "RI,RI,RI,RI,RIL,RIL,RRE,RRF,RXY,SI,SS") + (set_attr "cpu_facility" "*,*,*,*,extimm,extimm,*,z196,*,*,*") (set_attr "z10prop" "z10_super_E1, z10_super_E1, z10_super_E1, @@ -6166,6 +6365,7 @@ z10_super_E1, z10_super_E1, z10_super_E1, + *, z10_super_E1, *, *")]) @@ -6186,39 +6386,43 @@ (define_insn "*iorsi3_cc" [(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")) + (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0") + (match_operand:SI 2 "general_operand" "Os,d,d,R,T")) (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=d,d,d,d") + (set (match_operand:SI 0 "register_operand" "=d,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 + ork\t%0,%1,%2 o\t%0,%2 oy\t%0,%2" - [(set_attr "op_type" "RIL,RR,RX,RXY") - (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,z10_super_E1")]) + [(set_attr "op_type" "RIL,RR,RRF,RX,RXY") + (set_attr "cpu_facility" "*,*,z196,*,*") + (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")]) (define_insn "*iorsi3_cconly" [(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")) + (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0") + (match_operand:SI 2 "general_operand" "Os,d,d,R,T")) (const_int 0))) - (clobber (match_scratch:SI 0 "=d,d,d,d"))] + (clobber (match_scratch:SI 0 "=d,d,d,d,d"))] "s390_match_ccmode(insn, CCTmode)" "@ oilf\t%0,%o2 or\t%0,%2 + ork\t%0,%1,%2 o\t%0,%2 oy\t%0,%2" - [(set_attr "op_type" "RIL,RR,RX,RXY") - (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,z10_super_E1")]) + [(set_attr "op_type" "RIL,RR,RRF,RX,RXY") + (set_attr "cpu_facility" "*,*,z196,*,*") + (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super_E1,z10_super_E1")]) (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"))) + [(set (match_operand:SI 0 "nonimmediate_operand" "=d, d, d,d,d,d,d, AQ,Q") + (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0, 0, 0,0,d,0,0, 0,0") + (match_operand:SI 2 "general_operand" "N0HS0,N1HS0,Os,d,d,R,T,NxQS0,Q"))) (clobber (reg:CC CC_REGNUM))] "TARGET_ZARCH && s390_logical_operator_ok_p (operands)" "@ @@ -6226,15 +6430,18 @@ oill\t%0,%i2 oilf\t%0,%o2 or\t%0,%2 + ork\t%0,%1,%2 o\t%0,%2 oy\t%0,%2 # #" - [(set_attr "op_type" "RI,RI,RIL,RR,RX,RXY,SI,SS") + [(set_attr "op_type" "RI,RI,RIL,RR,RRF,RX,RXY,SI,SS") + (set_attr "cpu_facility" "*,*,*,*,z196,*,*,*,*") (set_attr "z10prop" "z10_super_E1, z10_super_E1, z10_super_E1, z10_super_E1, + *, z10_super_E1, z10_super_E1, *, @@ -6269,18 +6476,20 @@ ; (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"))) + [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q") + (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,d,0, 0,0") + (match_operand:HI 2 "general_operand" " d,d,n,NxQH0,Q"))) (clobber (reg:CC CC_REGNUM))] "TARGET_ZARCH && s390_logical_operator_ok_p (operands)" "@ or\t%0,%2 + ork\t%0,%1,%2 oill\t%0,%x2 # #" - [(set_attr "op_type" "RR,RI,SI,SS") - (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")]) + [(set_attr "op_type" "RR,RRF,RI,SI,SS") + (set_attr "cpu_facility" "*,z196,*,*,*") + (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,*")]) (define_insn "*iorhi3_esa" [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q") @@ -6310,19 +6519,22 @@ ; (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"))) + [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q") + (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,d,0,0,0,0") + (match_operand:QI 2 "general_operand" " d,d,n,n,n,Q"))) (clobber (reg:CC CC_REGNUM))] "TARGET_ZARCH && s390_logical_operator_ok_p (operands)" "@ or\t%0,%2 + ork\t%0,%1,%2 oill\t%0,%b2 oi\t%S0,%b2 oiy\t%S0,%b2 #" - [(set_attr "op_type" "RR,RI,SI,SIY,SS") - (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super,z10_super,*")]) + [(set_attr "op_type" "RR,RRF,RI,SI,SIY,SS") + (set_attr "cpu_facility" "*,z196,*,*,*,*") + (set_attr "z10prop" "z10_super_E1,*,z10_super_E1, + z10_super,z10_super,*")]) (define_insn "*iorqi3_esa" [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,Q") @@ -6349,7 +6561,8 @@ (clobber (reg:CC CC_REGNUM))] "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256" "oc\t%O0(%2,%R0),%S1" - [(set_attr "op_type" "SS")]) + [(set_attr "op_type" "SS") + (set_attr "z196prop" "z196_cracked")]) (define_split [(set (match_operand 0 "memory_operand" "") @@ -6414,47 +6627,52 @@ (define_insn "*xordi3_cc" [(set (reg CC_REGNUM) - (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") - (match_operand:DI 2 "general_operand" "d,RT")) + (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d, 0") + (match_operand:DI 2 "general_operand" " d,d,RT")) (const_int 0))) - (set (match_operand:DI 0 "register_operand" "=d,d") + (set (match_operand:DI 0 "register_operand" "=d,d, d") (xor:DI (match_dup 1) (match_dup 2)))] "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH" "@ xgr\t%0,%2 + xgrk\t%0,%1,%2 xg\t%0,%2" - [(set_attr "op_type" "RRE,RXY") - (set_attr "z10prop" "z10_super_E1,z10_super_E1")]) + [(set_attr "op_type" "RRE,RRF,RXY") + (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")]) (define_insn "*xordi3_cconly" [(set (reg CC_REGNUM) - (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") - (match_operand:DI 2 "general_operand" "d,RT")) + (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d, 0") + (match_operand:DI 2 "general_operand" " d,d,RT")) (const_int 0))) - (clobber (match_scratch:DI 0 "=d,d"))] + (clobber (match_scratch:DI 0 "=d,d, d"))] "s390_match_ccmode(insn, CCTmode) && TARGET_ZARCH" "@ xgr\t%0,%2 + xgrk\t%0,%1,%2 xg\t%0,%2" - [(set_attr "op_type" "RRE,RXY") - (set_attr "z10prop" "z10_super_E1,z10_super_E1")]) + [(set_attr "op_type" "RRE,RRF,RXY") + (set_attr "cpu_facility" "*,z196,*") + (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")]) (define_insn "*xordi3" - [(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,RT,NxQD0,Q"))) + [(set (match_operand:DI 0 "nonimmediate_operand" "=d, d,d,d, d, AQ,Q") + (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0, 0,0,d, 0, 0,0") + (match_operand:DI 2 "general_operand" "N0SD0,N1SD0,d,d,RT,NxQD0,Q"))) (clobber (reg:CC CC_REGNUM))] "TARGET_ZARCH && s390_logical_operator_ok_p (operands)" "@ xihf\t%0,%k2 xilf\t%0,%k2 xgr\t%0,%2 + xgrk\t%0,%1,%2 xg\t%0,%2 # #" - [(set_attr "op_type" "RIL,RIL,RRE,RXY,SI,SS") - (set_attr "cpu_facility" "extimm,extimm,*,*,*,*") - (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,z10_super_E1,*,*")]) + [(set_attr "op_type" "RIL,RIL,RRE,RRF,RXY,SI,SS") + (set_attr "cpu_facility" "extimm,extimm,*,z196,*,*,*") + (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1, + *,z10_super_E1,*,*")]) (define_split [(set (match_operand:DI 0 "s_operand" "") @@ -6472,50 +6690,59 @@ (define_insn "*xorsi3_cc" [(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")) + (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0") + (match_operand:SI 2 "general_operand" "Os,d,d,R,T")) (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=d,d,d,d") + (set (match_operand:SI 0 "register_operand" "=d,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 + xrk\t%0,%1,%2 x\t%0,%2 xy\t%0,%2" - [(set_attr "op_type" "RIL,RR,RX,RXY") - (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,z10_super_E1")]) + [(set_attr "op_type" "RIL,RR,RRF,RX,RXY") + (set_attr "cpu_facility" "*,*,z196,*,*") + (set_attr "z10prop" "z10_super_E1,z10_super_E1,*, + z10_super_E1,z10_super_E1")]) (define_insn "*xorsi3_cconly" [(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")) + (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0") + (match_operand:SI 2 "general_operand" "Os,d,d,R,T")) (const_int 0))) - (clobber (match_scratch:SI 0 "=d,d,d,d"))] + (clobber (match_scratch:SI 0 "=d,d,d,d,d"))] "s390_match_ccmode(insn, CCTmode)" "@ xilf\t%0,%o2 xr\t%0,%2 + xrk\t%0,%1,%2 x\t%0,%2 xy\t%0,%2" - [(set_attr "op_type" "RIL,RR,RX,RXY") - (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,z10_super_E1")]) + [(set_attr "op_type" "RIL,RR,RRF,RX,RXY") + (set_attr "cpu_facility" "*,*,z196,*,*") + (set_attr "z10prop" "z10_super_E1,z10_super_E1,*, + z10_super_E1,z10_super_E1")]) (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"))) + [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d, AQ,Q") + (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,d,0,0, 0,0") + (match_operand:SI 2 "general_operand" "Os,d,d,R,T,NxQS0,Q"))) (clobber (reg:CC CC_REGNUM))] "s390_logical_operator_ok_p (operands)" "@ xilf\t%0,%o2 xr\t%0,%2 + xrk\t%0,%1,%2 x\t%0,%2 xy\t%0,%2 # #" - [(set_attr "op_type" "RIL,RR,RX,RXY,SI,SS") - (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,z10_super_E1,*,*")]) + [(set_attr "op_type" "RIL,RR,RRF,RX,RXY,SI,SS") + (set_attr "cpu_facility" "*,*,z196,*,*,*,*") + (set_attr "z10prop" "z10_super_E1,z10_super_E1,*, + z10_super_E1,z10_super_E1,*,*")]) (define_split [(set (match_operand:SI 0 "s_operand" "") @@ -6532,18 +6759,20 @@ ; (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"))) + [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d, AQ,Q") + (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,d, 0,0") + (match_operand:HI 2 "general_operand" "Os,d,d,NxQH0,Q"))) (clobber (reg:CC CC_REGNUM))] "s390_logical_operator_ok_p (operands)" "@ xilf\t%0,%x2 xr\t%0,%2 + xrk\t%0,%1,%2 # #" - [(set_attr "op_type" "RIL,RR,SI,SS") - (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")]) + [(set_attr "op_type" "RIL,RR,RRF,SI,SS") + (set_attr "cpu_facility" "*,*,z196,*,*") + (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*,*")]) (define_split [(set (match_operand:HI 0 "s_operand" "") @@ -6560,19 +6789,21 @@ ; (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"))) + [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,d,Q,S,Q") + (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,d,0,0,0") + (match_operand:QI 2 "general_operand" "Os,d,d,n,n,Q"))) (clobber (reg:CC CC_REGNUM))] "s390_logical_operator_ok_p (operands)" "@ xilf\t%0,%b2 xr\t%0,%2 + xrk\t%0,%1,%2 xi\t%S0,%b2 xiy\t%S0,%b2 #" - [(set_attr "op_type" "RIL,RR,SI,SIY,SS") - (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super,z10_super,*")]) + [(set_attr "op_type" "RIL,RR,RRF,SI,SIY,SS") + (set_attr "cpu_facility" "*,*,z196,*,*,*") + (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,z10_super,z10_super,*")]) ; @@ -6644,7 +6875,8 @@ (clobber (reg:CC CC_REGNUM))] "INTVAL (operands[1]) >= 1 && INTVAL (operands[1]) <= 256" "xc\t%O0(%1,%R0),%S0" - [(set_attr "op_type" "SS")]) + [(set_attr "op_type" "SS") + (set_attr "z196prop" "z196_cracked")]) (define_peephole2 [(parallel @@ -7167,7 +7399,7 @@ ; ; (ashl|lshr)(di|si)3 instruction pattern(s). -; +; Left shifts and logical right shifts (define_expand "3" [(set (match_operand:DSI 0 "register_operand" "") @@ -7184,18 +7416,22 @@ "!TARGET_ZARCH" "sdl\t%0,%Y2" [(set_attr "op_type" "RS") - (set_attr "atype" "reg")]) - -; sll, srl, sllg, srlg -(define_insn "*3" - [(set (match_operand:GPR 0 "register_operand" "=d") - (SHIFT:GPR (match_operand:GPR 1 "register_operand" "") - (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))] - "" - "sl\t%0,<1>%Y2" - [(set_attr "op_type" "RS") (set_attr "atype" "reg") - (set_attr "z10prop" "z10_super_E1")]) + (set_attr "z196prop" "z196_cracked")]) + +; sll, srl, sllg, srlg, sllk, srlk +(define_insn "*3" + [(set (match_operand:GPR 0 "register_operand" "=d,d") + (SHIFT:GPR (match_operand:GPR 1 "register_operand" ",d") + (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")))] + "" + "@ + sl\t%0,<1>%Y2 + sl\t%0,%1,%Y2" + [(set_attr "op_type" "RS,RSY") + (set_attr "atype" "reg,reg") + (set_attr "cpu_facility" "*,z196") + (set_attr "z10prop" "z10_super_E1,*")]) ; sldl, srdl (define_insn "*di3_31_and" @@ -7208,21 +7444,24 @@ [(set_attr "op_type" "RS") (set_attr "atype" "reg")]) -; sll, srl, sllg, srlg +; sll, srl, sllg, srlg, sllk, srlk (define_insn "*3_and" - [(set (match_operand:GPR 0 "register_operand" "=d") - (SHIFT:GPR (match_operand:GPR 1 "register_operand" "") - (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y") - (match_operand:SI 3 "const_int_operand" "n"))))] + [(set (match_operand:GPR 0 "register_operand" "=d,d") + (SHIFT:GPR (match_operand:GPR 1 "register_operand" ",d") + (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y") + (match_operand:SI 3 "const_int_operand" "n,n"))))] "(INTVAL (operands[3]) & 63) == 63" - "sl\t%0,<1>%Y2" - [(set_attr "op_type" "RS") - (set_attr "atype" "reg") - (set_attr "z10prop" "z10_super_E1")]) + "@ + sl\t%0,<1>%Y2 + sl\t%0,%1,%Y2" + [(set_attr "op_type" "RS,RSY") + (set_attr "atype" "reg,reg") + (set_attr "cpu_facility" "*,z196") + (set_attr "z10prop" "z10_super_E1,*")]) ; ; ashr(di|si)3 instruction pattern(s). -; +; Arithmetic right shifts (define_expand "ashr3" [(parallel @@ -7266,44 +7505,53 @@ [(set_attr "op_type" "RS") (set_attr "atype" "reg")]) -; sra, srag +; sra, srag, srak (define_insn "*ashr3_cc" [(set (reg CC_REGNUM) - (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "") - (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")) + (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" ",d") + (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")) (const_int 0))) - (set (match_operand:GPR 0 "register_operand" "=d") + (set (match_operand:GPR 0 "register_operand" "=d,d") (ashiftrt:GPR (match_dup 1) (match_dup 2)))] "s390_match_ccmode(insn, CCSmode)" - "sra\t%0,<1>%Y2" - [(set_attr "op_type" "RS") - (set_attr "atype" "reg") - (set_attr "z10prop" "z10_super_E1")]) + "@ + sra\t%0,<1>%Y2 + sra\t%0,%1,%Y2" + [(set_attr "op_type" "RS,RSY") + (set_attr "atype" "reg,reg") + (set_attr "cpu_facility" "*,z196") + (set_attr "z10prop" "z10_super_E1,*")]) -; sra, srag +; sra, srag, srak (define_insn "*ashr3_cconly" [(set (reg CC_REGNUM) - (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "") - (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")) + (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" ",d") + (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y")) (const_int 0))) - (clobber (match_scratch:GPR 0 "=d"))] + (clobber (match_scratch:GPR 0 "=d,d"))] "s390_match_ccmode(insn, CCSmode)" - "sra\t%0,<1>%Y2" - [(set_attr "op_type" "RS") - (set_attr "atype" "reg") - (set_attr "z10prop" "z10_super_E1")]) + "@ + sra\t%0,<1>%Y2 + sra\t%0,%1,%Y2" + [(set_attr "op_type" "RS,RSY") + (set_attr "atype" "reg,reg") + (set_attr "cpu_facility" "*,z196") + (set_attr "z10prop" "z10_super_E1,*")]) ; sra, srag (define_insn "*ashr3" - [(set (match_operand:GPR 0 "register_operand" "=d") - (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "") - (match_operand:SI 2 "shift_count_or_setmem_operand" "Y"))) + [(set (match_operand:GPR 0 "register_operand" "=d,d") + (ashiftrt:GPR (match_operand:GPR 1 "register_operand" ",d") + (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y"))) (clobber (reg:CC CC_REGNUM))] "" - "sra\t%0,<1>%Y2" - [(set_attr "op_type" "RS") - (set_attr "atype" "reg") - (set_attr "z10prop" "z10_super_E1")]) + "@ + sra\t%0,<1>%Y2 + sra\t%0,%1,%Y2" + [(set_attr "op_type" "RS,RSY") + (set_attr "atype" "reg,reg") + (set_attr "cpu_facility" "*,z196") + (set_attr "z10prop" "z10_super_E1,*")]) ; shift pattern with implicit ANDs @@ -7346,47 +7594,55 @@ [(set_attr "op_type" "RS") (set_attr "atype" "reg")]) -; sra, srag +; sra, srag, srak (define_insn "*ashr3_cc_and" [(set (reg CC_REGNUM) - (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "") - (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y") - (match_operand:SI 3 "const_int_operand" "n"))) + (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" ",d") + (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y") + (match_operand:SI 3 "const_int_operand" "n,n"))) (const_int 0))) - (set (match_operand:GPR 0 "register_operand" "=d") + (set (match_operand:GPR 0 "register_operand" "=d,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\t%0,<1>%Y2" - [(set_attr "op_type" "RS") - (set_attr "atype" "reg") - (set_attr "z10prop" "z10_super_E1")]) + "@ + sra\t%0,<1>%Y2 + sra\t%0,%1,%Y2" + [(set_attr "op_type" "RS,RSY") + (set_attr "atype" "reg,reg") + (set_attr "cpu_facility" "*,z196") + (set_attr "z10prop" "z10_super_E1,*")]) -; sra, srag +; sra, srag, srak (define_insn "*ashr3_cconly_and" [(set (reg CC_REGNUM) - (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "") - (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y") - (match_operand:SI 3 "const_int_operand" "n"))) + (compare (ashiftrt:GPR (match_operand:GPR 1 "register_operand" ",d") + (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y") + (match_operand:SI 3 "const_int_operand" "n,n"))) (const_int 0))) - (clobber (match_scratch:GPR 0 "=d"))] + (clobber (match_scratch:GPR 0 "=d,d"))] "s390_match_ccmode(insn, CCSmode) && (INTVAL (operands[3]) & 63) == 63" - "sra\t%0,<1>%Y2" - [(set_attr "op_type" "RS") - (set_attr "atype" "reg") - (set_attr "z10prop" "z10_super_E1")]) + "@ + sra\t%0,<1>%Y2 + sra\t%0,%1,%Y2" + [(set_attr "op_type" "RS,RSY") + (set_attr "atype" "reg,reg") + (set_attr "cpu_facility" "*,z196") + (set_attr "z10prop" "z10_super_E1,*")]) -; sra, srag +; sra, srag, srak (define_insn "*ashr3_and" - [(set (match_operand:GPR 0 "register_operand" "=d") - (ashiftrt:GPR (match_operand:GPR 1 "register_operand" "") - (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y") - (match_operand:SI 3 "const_int_operand" "n")))) + [(set (match_operand:GPR 0 "register_operand" "=d,d") + (ashiftrt:GPR (match_operand:GPR 1 "register_operand" ",d") + (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y,Y") + (match_operand:SI 3 "const_int_operand" "n,n")))) (clobber (reg:CC CC_REGNUM))] "(INTVAL (operands[3]) & 63) == 63" - "sra\t%0,<1>%Y2" - [(set_attr "op_type" "RS") - (set_attr "atype" "reg") - (set_attr "z10prop" "z10_super_E1")]) + "@ + sra\t%0,<1>%Y2 + sra\t%0,%1,%Y2" + [(set_attr "op_type" "RS,RSY") + (set_attr "atype" "reg,reg") + (set_attr "z10prop" "z10_super_E1,*")]) ;; @@ -7941,7 +8197,8 @@ (const_string "RR") (const_string "RX"))) (set_attr "type" "branch") (set_attr "atype" "agen") - (set_attr "z10prop" "z10_c")]) + (set_attr "z10prop" "z10_c") + (set_attr "z196prop" "z196_cracked")]) (define_insn_and_split "doloop_di" [(set (pc) @@ -8261,7 +8518,8 @@ && GET_MODE (operands[2]) == Pmode" "bras\t%2,%0" [(set_attr "op_type" "RI") - (set_attr "type" "jsr")]) + (set_attr "type" "jsr") + (set_attr "z196prop" "z196_cracked")]) (define_insn "*brasl" [(call (mem:QI (match_operand 0 "bras_sym_operand" "X")) @@ -8272,7 +8530,8 @@ && GET_MODE (operands[2]) == Pmode" "brasl\t%2,%0" [(set_attr "op_type" "RIL") - (set_attr "type" "jsr")]) + (set_attr "type" "jsr") + (set_attr "z196prop" "z196_cracked")]) (define_insn "*basr" [(call (mem:QI (match_operand 0 "address_operand" "ZQZR")) @@ -8289,7 +8548,8 @@ (if_then_else (match_operand 0 "register_operand" "") (const_string "RR") (const_string "RX"))) (set_attr "type" "jsr") - (set_attr "atype" "agen")]) + (set_attr "atype" "agen") + (set_attr "z196prop" "z196_cracked")]) ; ; call_value instruction pattern(s). @@ -8317,7 +8577,8 @@ && GET_MODE (operands[3]) == Pmode" "bras\t%3,%1" [(set_attr "op_type" "RI") - (set_attr "type" "jsr")]) + (set_attr "type" "jsr") + (set_attr "z196prop" "z196_cracked")]) (define_insn "*brasl_r" [(set (match_operand 0 "" "") @@ -8329,7 +8590,8 @@ && GET_MODE (operands[3]) == Pmode" "brasl\t%3,%1" [(set_attr "op_type" "RIL") - (set_attr "type" "jsr")]) + (set_attr "type" "jsr") + (set_attr "z196prop" "z196_cracked")]) (define_insn "*basr_r" [(set (match_operand 0 "" "") @@ -8347,7 +8609,8 @@ (if_then_else (match_operand 1 "register_operand" "") (const_string "RR") (const_string "RX"))) (set_attr "type" "jsr") - (set_attr "atype" "agen")]) + (set_attr "atype" "agen") + (set_attr "z196prop" "z196_cracked")]) ;; ;;- Thread-local storage support. @@ -8416,7 +8679,8 @@ && GET_MODE (operands[3]) == Pmode" "bras\t%3,%1%J4" [(set_attr "op_type" "RI") - (set_attr "type" "jsr")]) + (set_attr "type" "jsr") + (set_attr "z196prop" "z196_cracked")]) (define_insn "*brasl_tls" [(set (match_operand 0 "" "") @@ -8429,7 +8693,8 @@ && GET_MODE (operands[3]) == Pmode" "brasl\t%3,%1%J4" [(set_attr "op_type" "RIL") - (set_attr "type" "jsr")]) + (set_attr "type" "jsr") + (set_attr "z196prop" "z196_cracked")]) (define_insn "*basr_tls" [(set (match_operand 0 "" "") @@ -8448,7 +8713,8 @@ (if_then_else (match_operand 1 "register_operand" "") (const_string "RR") (const_string "RX"))) (set_attr "type" "jsr") - (set_attr "atype" "agen")]) + (set_attr "atype" "agen") + (set_attr "z196prop" "z196_cracked")]) ;; ;;- Atomic operations @@ -8557,6 +8823,36 @@ "s390_expand_atomic (mode, SET, operands[0], operands[1], operands[2], false); DONE;") +; z196 load and add, xor, or and and instructions + +; lan, lang, lao, laog, lax, laxg, laa, laag +(define_insn "sync_" + [(parallel + [(set (match_operand:GPR 0 "memory_operand" "+QS") + (unspec_volatile:GPR + [(ATOMIC_Z196:GPR (match_dup 0) + (match_operand:GPR 1 "general_operand" "d"))] + UNSPECV_ATOMIC_OP)) + (clobber (match_scratch:GPR 2 "=d")) + (clobber (reg:CC CC_REGNUM))])] + "TARGET_Z196" + "la\t%2,%1,%0") + +; lan, lang, lao, laog, lax, laxg, laa, laag +(define_insn "sync_old_" + [(parallel + [(set (match_operand:GPR 0 "register_operand" "=d") + (match_operand:GPR 1 "memory_operand" "+QS")) + (set (match_dup 1) + (unspec_volatile + [(ATOMIC_Z196:GPR (match_dup 1) + (match_operand:GPR 2 "general_operand" "d"))] + UNSPECV_ATOMIC_OP)) + (clobber (reg:CC CC_REGNUM))])] + "TARGET_Z196" + "la\t%0,%2,%1") + + (define_expand "sync_" [(set (match_operand:HQI 0 "memory_operand") (ATOMIC:HQI (match_dup 0) @@ -8775,7 +9071,8 @@ "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode" "basr\t%0,0" [(set_attr "op_type" "RR") - (set_attr "type" "la")]) + (set_attr "type" "la") + (set_attr "z196prop" "z196_cracked")]) (define_insn "main_base_31_large" [(set (match_operand 0 "register_operand" "=a") @@ -8783,7 +9080,8 @@ (set (pc) (label_ref (match_operand 2 "" "")))] "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode" "bras\t%0,%2" - [(set_attr "op_type" "RI")]) + [(set_attr "op_type" "RI") + (set_attr "z196prop" "z196_cracked")]) (define_insn "main_base_64" [(set (match_operand 0 "register_operand" "=a") @@ -8811,7 +9109,8 @@ "!TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode" "basr\t%0,0\;la\t%0,%1-.(%0)" [(set_attr "length" "6") - (set_attr "type" "la")]) + (set_attr "type" "la") + (set_attr "z196prop" "z196_cracked")]) (define_insn "reload_base_64" [(set (match_operand 0 "register_operand" "=a") @@ -8984,7 +9283,8 @@ } [(set_attr "type" "load,larl") (set_attr "op_type" "RXY,RIL") - (set_attr "z10prop" "z10_super")]) + (set_attr "z10prop" "z10_super") + (set_attr "z196prop" "z196_alone")]) ; @@ -9001,3 +9301,107 @@ [(set_attr "type" "*,load") (set_attr "op_type" "RRE,RXY") (set_attr "z10prop" "z10_super")]) + + +; +; Population count instruction +; + +; The S/390 popcount instruction counts the bits of op1 in 8 byte +; portions and stores the result in the corresponding bytes in op0. +(define_insn "*popcount" + [(set (match_operand:INT 0 "register_operand" "=d") + (unspec:INT [(match_operand:INT 1 "register_operand" "d")] UNSPEC_POPCNT)) + (clobber (reg:CC CC_REGNUM))] + "TARGET_Z196" + "popcnt\t%0,%1" + [(set_attr "op_type" "RRE")]) + +(define_expand "popcountdi2" + [; popcnt op0, op1 + (parallel [(set (match_operand:DI 0 "register_operand" "") + (unspec:DI [(match_operand:DI 1 "register_operand")] + UNSPEC_POPCNT)) + (clobber (reg:CC CC_REGNUM))]) + ; sllg op2, op0, 32 + (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 32))) + ; agr op0, op2 + (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2))) + (clobber (reg:CC CC_REGNUM))]) + ; sllg op2, op0, 16 + (set (match_operand:DI 2 "register_operand" "") + (ashift:DI (match_dup 0) (const_int 16))) + ; agr op0, op2 + (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2))) + (clobber (reg:CC CC_REGNUM))]) + ; sllg op2, op0, 8 + (set (match_dup 2) (ashift:DI (match_dup 0) (const_int 8))) + ; agr op0, op2 + (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2))) + (clobber (reg:CC CC_REGNUM))]) + ; srlg op0, op0, 56 + (set (match_dup 0) (lshiftrt:DI (match_dup 0) (const_int 56)))] + "TARGET_Z196 && TARGET_64BIT" + "operands[2] = gen_reg_rtx (DImode);") + +(define_expand "popcountsi2" + [; popcnt op0, op1 + (parallel [(set (match_operand:SI 0 "register_operand" "") + (unspec:SI [(match_operand:SI 1 "register_operand")] + UNSPEC_POPCNT)) + (clobber (reg:CC CC_REGNUM))]) + ; sllk op2, op0, 16 + (set (match_operand:SI 2 "register_operand" "") + (ashift:SI (match_dup 0) (const_int 16))) + ; ar op0, op2 + (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2))) + (clobber (reg:CC CC_REGNUM))]) + ; sllk op2, op0, 8 + (set (match_dup 2) (ashift:SI (match_dup 0) (const_int 8))) + ; ar op0, op2 + (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2))) + (clobber (reg:CC CC_REGNUM))]) + ; srl op0, op0, 24 + (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))] + "TARGET_Z196" + "operands[2] = gen_reg_rtx (SImode);") + +(define_expand "popcounthi2" + [; popcnt op0, op1 + (parallel [(set (match_operand:HI 0 "register_operand" "") + (unspec:HI [(match_operand:HI 1 "register_operand")] + UNSPEC_POPCNT)) + (clobber (reg:CC CC_REGNUM))]) + ; sllk op2, op0, 8 + (set (match_operand:SI 2 "register_operand" "") + (ashift:SI (match_dup 0) (const_int 8))) + ; ar op0, op2 + (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2))) + (clobber (reg:CC CC_REGNUM))]) + ; srl op0, op0, 8 + (set (match_dup 0) (lshiftrt:HI (match_dup 0) (const_int 8)))] + "TARGET_Z196" + "operands[2] = gen_reg_rtx (SImode);") + +(define_expand "popcountqi2" + [; popcnt op0, op1 + (parallel [(set (match_operand:QI 0 "register_operand" "") + (unspec:QI [(match_operand:QI 1 "register_operand")] + UNSPEC_POPCNT)) + (clobber (reg:CC CC_REGNUM))])] + "TARGET_Z196" + "") + +;; +;;- Copy sign instructions +;; + +(define_insn "copysign3" + [(set (match_operand:FP 0 "register_operand" "=f") + (unspec:FP [(match_operand:FP 1 "register_operand" "") + (match_operand:FP 2 "register_operand" "f")] + UNSPEC_COPYSIGN))] + "TARGET_Z196" + "cpsdr\t%0,%2,%1" + [(set_attr "op_type" "RRF") + (set_attr "type" "fsimp")])