diff options
author | Mike Frysinger <vapier@gentoo.org> | 2008-12-25 22:17:02 +0000 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2008-12-25 22:17:02 +0000 |
commit | 7a23fc13231846a966e20905863fe161acaa3c9d (patch) | |
tree | b20f1ccca1b42365d1bbcf0977ddbfa51df289ae /4.3.2 | |
parent | merge freebsd fixups #192403 (diff) | |
download | gcc-patches-7a23fc13231846a966e20905863fe161acaa3c9d.tar.gz gcc-patches-7a23fc13231846a966e20905863fe161acaa3c9d.tar.bz2 gcc-patches-7a23fc13231846a966e20905863fe161acaa3c9d.zip |
add exec fix for sh and z10 support for s390
Diffstat (limited to '4.3.2')
-rw-r--r-- | 4.3.2/gentoo/20_all_s390-gcc-4.3.2-z10-complete.patch | 6383 | ||||
-rw-r--r-- | 4.3.2/gentoo/73_all_sh-libgcc-stacks.patch | 44 | ||||
-rw-r--r-- | 4.3.2/gentoo/README.history | 2 |
3 files changed, 6429 insertions, 0 deletions
diff --git a/4.3.2/gentoo/20_all_s390-gcc-4.3.2-z10-complete.patch b/4.3.2/gentoo/20_all_s390-gcc-4.3.2-z10-complete.patch new file mode 100644 index 0000000..acda878 --- /dev/null +++ b/4.3.2/gentoo/20_all_s390-gcc-4.3.2-z10-complete.patch @@ -0,0 +1,6383 @@ +http://www.ibm.com/developerworks/linux/linux390/toolchain.html#gcc-4.3.2 + +This patch enables gcc 4.3.2 to generate code using the new IBM System +z10 hardware instructions and provides z10 specific instructions +scheduling. When the -march=z10 option is specified, gcc makes use of +the z10 instruction extension facility to generate faster executables +which are limited to run on a z10 or higher. z10 specific instruction +scheduling is enabled by default when using the -march=z10 option but +can also be requested separately using the -mtune=z10 option. + +Index: gcc/doc/tm.texi +=================================================================== +--- gcc/doc/tm.texi (revision 141434) ++++ gcc/doc/tm.texi (working copy) +@@ -5297,6 +5297,17 @@ + Format}. + @end defmac + ++@defmac TARGET_MEM_CONSTRAINT ++A single character to be used instead of the default @code{'m'} ++character for general memory addresses. This defines the constraint ++letter which matches the memory addresses accepted by ++@code{GO_IF_LEGITIMATE_ADDRESS_P}. Define this macro if you want to ++support new address formats in your back end without changing the ++semantics of the @code{'m'} constraint. This is necessary in order to ++preserve functionality of inline assembly constructs using the ++@code{'m'} constraint. ++@end defmac ++ + @defmac FIND_BASE_TERM (@var{x}) + A C expression to determine the base term of address @var{x}. + This macro is used in only one place: `find_base_term' in alias.c. +Index: gcc/doc/md.texi +=================================================================== +--- gcc/doc/md.texi (revision 141434) ++++ gcc/doc/md.texi (working copy) +@@ -1050,6 +1050,7 @@ + * Multi-Alternative:: When an insn has two alternative constraint-patterns. + * Class Preferences:: Constraints guide which hard register to put things in. + * Modifiers:: More precise control over effects of constraints. ++* Disable Insn Alternatives:: Disable insn alternatives using the @code{enabled} attribute. + * Machine Constraints:: Existing constraints for some particular machines. + * Define Constraints:: How to define machine-specific constraints. + * C Constraint Interface:: How to test constraints from C code. +@@ -1085,6 +1086,8 @@ + @item @samp{m} + A memory operand is allowed, with any kind of address that the machine + supports in general. ++Note that the letter used for the general memory constraint can be ++re-defined by a back end using the @code{TARGET_MEM_CONSTRAINT} macro. + + @cindex offsettable address + @cindex @samp{o} in constraint +@@ -3091,6 +3094,99 @@ + @end table + + @ifset INTERNALS ++@node Disable Insn Alternatives ++@subsection Disable insn alternatives using the @code{enabled} attribute ++@cindex enabled ++ ++The @code{enabled} insn attribute may be used to disable certain insn ++alternatives for machine-specific reasons. This is useful when adding ++new instructions to an existing pattern which are only available for ++certain cpu architecture levels as specified with the @code{-march=} ++option. ++ ++If an insn alternative is disabled, then it will never be used. The ++compiler treats the constraints for the disabled alternative as ++unsatisfiable. ++ ++In order to make use of the @code{enabled} attribute a back end has to add ++in the machine description files: ++ ++@enumerate ++@item ++A definition of the @code{enabled} insn attribute. The attribute is ++defined as usual using the @code{define_attr} command. This ++definition should be based on other insn attributes and/or target flags. ++The @code{enabled} attribute is a numeric attribute and should evaluate to ++@code{(const_int 1)} for an enabled alternative and to ++@code{(const_int 0)} otherwise. ++@item ++A definition of another insn attribute used to describe for what ++reason an insn alternative might be available or ++not. E.g. @code{cpu_facility} as in the example below. ++@item ++An assignement for the second attribute to each insn definition ++combining instructions which are not all available under the same ++circumstances. (Note: It obviously only makes sense for definitions ++with more than one alternative. Otherwise the insn pattern should be ++disabled or enabled using the insn condition.) ++@end enumerate ++ ++E.g. the following two patterns could easily be merged using the @code{enabled} ++attribute: ++ ++@smallexample ++ ++(define_insn "*movdi_old" ++ [(set (match_operand:DI 0 "register_operand" "=d") ++ (match_operand:DI 1 "register_operand" " d"))] ++ "!TARGET_NEW" ++ "lgr %0,%1") ++ ++(define_insn "*movdi_new" ++ [(set (match_operand:DI 0 "register_operand" "=d,f,d") ++ (match_operand:DI 1 "register_operand" " d,d,f"))] ++ "TARGET_NEW" ++ "@@ ++ lgr %0,%1 ++ ldgr %0,%1 ++ lgdr %0,%1") ++ ++@end smallexample ++ ++to: ++ ++@smallexample ++ ++(define_insn "*movdi_combined" ++ [(set (match_operand:DI 0 "register_operand" "=d,f,d") ++ (match_operand:DI 1 "register_operand" " d,d,f"))] ++ "" ++ "@@ ++ lgr %0,%1 ++ ldgr %0,%1 ++ lgdr %0,%1" ++ [(set_attr "cpu_facility" "*,new,new")]) ++ ++@end smallexample ++ ++with the @code{enabled} attribute defined like this: ++ ++@smallexample ++ ++(define_attr "cpu_facility" "standard,new" (const_string "standard")) ++ ++(define_attr "enabled" "" ++ (cond [(eq_attr "cpu_facility" "standard") (const_int 1) ++ (and (eq_attr "cpu_facility" "new") ++ (ne (symbol_ref "TARGET_NEW") (const_int 0))) ++ (const_int 1)] ++ (const_int 0))) ++ ++@end smallexample ++ ++@end ifset ++ ++@ifset INTERNALS + @node Define Constraints + @subsection Defining Machine-Specific Constraints + @cindex defining constraints +@@ -6514,6 +6610,22 @@ + defined and the function to obtain the attribute's value will return + @code{int}. + ++There are attributes which are tied to a specific meaning. These ++attributes are not free to use for other purposes: ++ ++@table @code ++@item length ++The @code{length} attribute is used to calculate the length of emitted ++code chunks. This is especially important when verifying branch ++distances. @xref{Insn Lengths}. ++ ++@item enabled ++The @code{enabled} attribute can be defined to prevent certain ++alternatives of an insn definition from being used during code ++generation. @xref{Disable Insn Alternatives}. ++ ++@end table ++ + @end ifset + @ifset INTERNALS + @node Expressions +Index: gcc/postreload.c +=================================================================== +--- gcc/postreload.c (revision 141434) ++++ gcc/postreload.c (working copy) +@@ -542,12 +542,12 @@ + case '*': case '%': + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': +- case 'm': case '<': case '>': case 'V': case 'o': ++ case '<': case '>': case 'V': case 'o': + case 'E': case 'F': case 'G': case 'H': + case 's': case 'i': case 'n': + case 'I': case 'J': case 'K': case 'L': + case 'M': case 'N': case 'O': case 'P': +- case 'p': case 'X': ++ case 'p': case 'X': case TARGET_MEM_CONSTRAINT: + /* These don't say anything we care about. */ + break; + +Index: gcc/defaults.h +=================================================================== +--- gcc/defaults.h (revision 141434) ++++ gcc/defaults.h (working copy) +@@ -902,6 +902,10 @@ + #define LEGITIMATE_PIC_OPERAND_P(X) 1 + #endif + ++#ifndef TARGET_MEM_CONSTRAINT ++#define TARGET_MEM_CONSTRAINT 'm' ++#endif ++ + #ifndef REVERSIBLE_CC_MODE + #define REVERSIBLE_CC_MODE(MODE) 0 + #endif +Index: gcc/reload.c +=================================================================== +--- gcc/reload.c (revision 141434) ++++ gcc/reload.c (working copy) +@@ -2544,7 +2544,7 @@ + int noperands; + /* These start out as the constraints for the insn + and they are chewed up as we consider alternatives. */ +- char *constraints[MAX_RECOG_OPERANDS]; ++ const char *constraints[MAX_RECOG_OPERANDS]; + /* These are the preferred classes for an operand, or NO_REGS if it isn't + a register. */ + enum reg_class preferred_class[MAX_RECOG_OPERANDS]; +@@ -2651,7 +2651,8 @@ + + memcpy (operand_mode, recog_data.operand_mode, + noperands * sizeof (enum machine_mode)); +- memcpy (constraints, recog_data.constraints, noperands * sizeof (char *)); ++ memcpy (constraints, recog_data.constraints, ++ noperands * sizeof (const char *)); + + commutative = -1; + +@@ -2662,8 +2663,9 @@ + + for (i = 0; i < noperands; i++) + { +- char *p; ++ const char *p; + int c; ++ char *end; + + substed_operand[i] = recog_data.operand[i]; + p = constraints[i]; +@@ -2707,7 +2709,8 @@ + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + { +- c = strtoul (p - 1, &p, 10); ++ c = strtoul (p - 1, &end, 10); ++ p = end; + + operands_match[c][i] + = operands_match_p (recog_data.operand[c], +@@ -2935,11 +2938,21 @@ + a bad register class to only count 1/3 as much. */ + int reject = 0; + ++ if (!recog_data.alternative_enabled_p[this_alternative_number]) ++ { ++ int i; ++ ++ for (i = 0; i < recog_data.n_operands; i++) ++ constraints[i] = skip_alternative (constraints[i]); ++ ++ continue; ++ } ++ + this_earlyclobber = 0; + + for (i = 0; i < noperands; i++) + { +- char *p = constraints[i]; ++ const char *p = constraints[i]; + char *end; + int len; + int win = 0; +@@ -3203,7 +3216,7 @@ + badop = 0; + break; + +- case 'm': ++ case TARGET_MEM_CONSTRAINT: + if (force_reload) + break; + if (MEM_P (operand) +@@ -3738,7 +3751,7 @@ + address_reloaded[commutative + 1] = t; + + memcpy (constraints, recog_data.constraints, +- noperands * sizeof (char *)); ++ noperands * sizeof (const char *)); + goto try_swapped; + } + else +@@ -4555,7 +4568,7 @@ + while (*constraint++ != ','); + altnum--; + } +- /* Scan the requested alternative for 'm' or 'o'. ++ /* Scan the requested alternative for TARGET_MEM_CONSTRAINT or 'o'. + If one of them is present, this alternative accepts the result of + passing a constant-pool reference through find_reloads_toplev. + +@@ -4566,7 +4579,7 @@ + for (; (c = *constraint) && c != ',' && c != '#'; + constraint += CONSTRAINT_LEN (c, constraint)) + { +- if (c == 'm' || c == 'o') ++ if (c == TARGET_MEM_CONSTRAINT || c == 'o') + return true; + #ifdef EXTRA_CONSTRAINT_STR + if (EXTRA_MEMORY_CONSTRAINT (c, constraint) +Index: gcc/genoutput.c +=================================================================== +--- gcc/genoutput.c (revision 141434) ++++ gcc/genoutput.c (working copy) +@@ -1122,7 +1122,10 @@ + unsigned int namelen = strlen (name); + struct constraint_data **iter, **slot, *new; + +- if (strchr (indep_constraints, name[0])) ++ /* The 'm' constraint is special here since that constraint letter ++ can be overridden by the back end by defining the ++ TARGET_MEM_CONSTRAINT macro. */ ++ if (strchr (indep_constraints, name[0]) && name[0] != 'm') + { + if (name[1] == '\0') + message_with_line (lineno, "constraint letter '%s' cannot be " +Index: gcc/recog.c +=================================================================== +--- gcc/recog.c (revision 141434) ++++ gcc/recog.c (working copy) +@@ -60,6 +60,14 @@ + #endif + #endif + ++#ifndef HAVE_ATTR_enabled ++static inline bool ++get_attr_enabled (rtx insn ATTRIBUTE_UNUSED) ++{ ++ return true; ++} ++#endif ++ + static void validate_replace_rtx_1 (rtx *, rtx, rtx, rtx); + static void validate_replace_src_1 (rtx *, void *); + static rtx split_insn (rtx); +@@ -1550,7 +1558,7 @@ + result = 1; + break; + +- case 'm': ++ case TARGET_MEM_CONSTRAINT: + case 'V': /* non-offsettable */ + if (memory_operand (op, VOIDmode)) + result = 1; +@@ -1684,16 +1692,14 @@ + result = 1; + } + #ifdef EXTRA_CONSTRAINT_STR ++ else if (EXTRA_MEMORY_CONSTRAINT (c, constraint)) ++ /* Every memory operand can be reloaded to fit. */ ++ result = result || memory_operand (op, VOIDmode); ++ else if (EXTRA_ADDRESS_CONSTRAINT (c, constraint)) ++ /* Every address operand can be reloaded to fit. */ ++ result = result || address_operand (op, VOIDmode); + else if (EXTRA_CONSTRAINT_STR (op, c, constraint)) + result = 1; +- else if (EXTRA_MEMORY_CONSTRAINT (c, constraint) +- /* Every memory operand can be reloaded to fit. */ +- && memory_operand (op, VOIDmode)) +- result = 1; +- else if (EXTRA_ADDRESS_CONSTRAINT (c, constraint) +- /* Every address operand can be reloaded to fit. */ +- && address_operand (op, VOIDmode)) +- result = 1; + #endif + break; + } +@@ -1927,11 +1933,9 @@ + int noperands; + rtx body = PATTERN (insn); + +- recog_data.insn = NULL; + recog_data.n_operands = 0; + recog_data.n_alternatives = 0; + recog_data.n_dups = 0; +- which_alternative = -1; + + switch (GET_CODE (body)) + { +@@ -2011,6 +2015,22 @@ + : OP_IN); + + gcc_assert (recog_data.n_alternatives <= MAX_RECOG_ALTERNATIVES); ++ ++ if (INSN_CODE (insn) < 0) ++ for (i = 0; i < recog_data.n_alternatives; i++) ++ recog_data.alternative_enabled_p[i] = true; ++ else ++ { ++ recog_data.insn = insn; ++ for (i = 0; i < recog_data.n_alternatives; i++) ++ { ++ which_alternative = i; ++ recog_data.alternative_enabled_p[i] = get_attr_enabled (insn); ++ } ++ } ++ ++ recog_data.insn = NULL; ++ which_alternative = -1; + } + + /* After calling extract_insn, you can use this function to extract some +@@ -2040,6 +2060,12 @@ + op_alt[j].matches = -1; + op_alt[j].matched = -1; + ++ if (!recog_data.alternative_enabled_p[j]) ++ { ++ p = skip_alternative (p); ++ continue; ++ } ++ + if (*p == '\0' || *p == ',') + { + op_alt[j].anything_ok = 1; +@@ -2089,7 +2115,7 @@ + } + continue; + +- case 'm': ++ case TARGET_MEM_CONSTRAINT: + op_alt[j].memory_ok = 1; + break; + case '<': +@@ -2209,6 +2235,17 @@ + int lose = 0; + funny_match_index = 0; + ++ if (!recog_data.alternative_enabled_p[which_alternative]) ++ { ++ int i; ++ ++ for (i = 0; i < recog_data.n_operands; i++) ++ constraints[i] = skip_alternative (constraints[i]); ++ ++ which_alternative++; ++ continue; ++ } ++ + for (opno = 0; opno < recog_data.n_operands; opno++) + { + rtx op = recog_data.operand[opno]; +@@ -2362,7 +2399,7 @@ + win = 1; + break; + +- case 'm': ++ case TARGET_MEM_CONSTRAINT: + /* Memory operands must be valid, to the extent + required by STRICT. */ + if (MEM_P (op)) +Index: gcc/recog.h +=================================================================== +--- gcc/recog.h (revision 141434) ++++ gcc/recog.h (working copy) +@@ -50,7 +50,8 @@ + + /* Nonzero if '&' was found in the constraint string. */ + unsigned int earlyclobber:1; +- /* Nonzero if 'm' was found in the constraint string. */ ++ /* Nonzero if TARGET_MEM_CONSTRAINT was found in the constraint ++ string. */ + unsigned int memory_ok:1; + /* Nonzero if 'o' was found in the constraint string. */ + unsigned int offmem_ok:1; +@@ -142,6 +143,19 @@ + } + #endif + ++/* Skip chars until the next ',' or the end of the string. This is ++ useful to skip alternatives in a constraint string. */ ++static inline const char * ++skip_alternative (const char *p) ++{ ++ const char *r = p; ++ while (*r != '\0' && *r != ',') ++ r++; ++ if (*r == ',') ++ r++; ++ return r; ++} ++ + /* Nonzero means volatile operands are recognized. */ + extern int volatile_ok; + +@@ -201,6 +215,12 @@ + /* The number of alternatives in the constraints for the insn. */ + char n_alternatives; + ++ /* Specifies whether an insn alternative is enabled using the ++ `enabled' attribute in the insn pattern definition. For back ++ ends not using the `enabled' attribute the array fields are ++ always set to `true' in expand_insn. */ ++ bool alternative_enabled_p [MAX_RECOG_ALTERNATIVES]; ++ + /* In case we are caching, hold insn data was generated for. */ + rtx insn; + }; +Index: gcc/genpreds.c +=================================================================== +--- gcc/genpreds.c (revision 141434) ++++ gcc/genpreds.c (working copy) +@@ -690,8 +690,11 @@ + for (iter_ = first_constraint; iter_; iter_ = iter_->next_textual) + + /* These letters, and all names beginning with them, are reserved for +- generic constraints. */ +-static const char generic_constraint_letters[] = "EFVXgimnoprs"; ++ generic constraints. ++ The 'm' constraint is not mentioned here since that constraint ++ letter can be overridden by the back end by defining the ++ TARGET_MEM_CONSTRAINT macro. */ ++static const char generic_constraint_letters[] = "EFVXginoprs"; + + /* Machine-independent code expects that constraints with these + (initial) letters will allow only (a subset of all) CONST_INTs. */ +Index: gcc/regclass.c +=================================================================== +--- gcc/regclass.c (revision 141434) ++++ gcc/regclass.c (working copy) +@@ -1141,8 +1141,9 @@ + record_address_regs (GET_MODE (recog_data.operand[i]), + XEXP (recog_data.operand[i], 0), + 0, MEM, SCRATCH, frequency * 2); +- else if (constraints[i][0] == 'p' +- || EXTRA_ADDRESS_CONSTRAINT (constraints[i][0], constraints[i])) ++ else if (recog_data.alternative_enabled_p[0] ++ && (constraints[i][0] == 'p' ++ || EXTRA_ADDRESS_CONSTRAINT (constraints[i][0], constraints[i]))) + record_address_regs (VOIDmode, recog_data.operand[i], 0, ADDRESS, + SCRATCH, frequency * 2); + } +@@ -1699,7 +1700,7 @@ + [(int) base_reg_class (VOIDmode, ADDRESS, SCRATCH)]; + break; + +- case 'm': case 'o': case 'V': ++ case TARGET_MEM_CONSTRAINT: case 'o': case 'V': + /* It doesn't seem worth distinguishing between offsettable + and non-offsettable addresses here. */ + allows_mem[i] = 1; +@@ -1930,6 +1931,9 @@ + if (alt_fail) + continue; + ++ if (!recog_data.alternative_enabled_p[alt]) ++ continue; ++ + /* Finally, update the costs with the information we've calculated + about this alternative. */ + +Index: gcc/config.gcc +=================================================================== +--- gcc/config.gcc (revision 141434) ++++ gcc/config.gcc (working copy) +@@ -3155,7 +3155,7 @@ + for which in arch tune; do + eval "val=\$with_$which" + case ${val} in +- "" | g5 | g6 | z900 | z990 | z9-109 | z9-ec) ++ "" | g5 | g6 | z900 | z990 | z9-109 | z9-ec | z10) + # OK + ;; + *) +Index: gcc/config/s390/s390.c +=================================================================== +--- gcc/config/s390/s390.c (revision 141434) ++++ gcc/config/s390/s390.c (working copy) +@@ -1,8 +1,9 @@ + /* Subroutines used for code generation on IBM S/390 and zSeries + Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, +- 2007 Free Software Foundation, Inc. ++ 2007, 2008 Free Software Foundation, Inc. + Contributed by Hartmut Penner (hpenner@de.ibm.com) and +- Ulrich Weigand (uweigand@de.ibm.com). ++ Ulrich Weigand (uweigand@de.ibm.com) and ++ Andreas Krebbel (Andreas.Krebbel@de.ibm.com). + + This file is part of GCC. + +@@ -188,6 +189,38 @@ + COSTS_N_INSNS (24), /* DSGR */ + }; + ++static const ++struct processor_costs z10_cost = ++{ ++ COSTS_N_INSNS (10), /* M */ ++ COSTS_N_INSNS (10), /* MGHI */ ++ COSTS_N_INSNS (10), /* MH */ ++ COSTS_N_INSNS (10), /* MHI */ ++ COSTS_N_INSNS (10), /* ML */ ++ COSTS_N_INSNS (10), /* MR */ ++ COSTS_N_INSNS (10), /* MS */ ++ COSTS_N_INSNS (10), /* MSG */ ++ COSTS_N_INSNS (10), /* MSGF */ ++ COSTS_N_INSNS (10), /* MSGFR */ ++ COSTS_N_INSNS (10), /* MSGR */ ++ COSTS_N_INSNS (10), /* MSR */ ++ COSTS_N_INSNS (10), /* multiplication in DFmode */ ++ COSTS_N_INSNS (50), /* MXBR */ ++ COSTS_N_INSNS (120), /* SQXBR */ ++ COSTS_N_INSNS (52), /* SQDBR */ ++ COSTS_N_INSNS (38), /* SQEBR */ ++ COSTS_N_INSNS (10), /* MADBR */ ++ COSTS_N_INSNS (10), /* MAEBR */ ++ COSTS_N_INSNS (111), /* DXBR */ ++ COSTS_N_INSNS (39), /* DDBR */ ++ COSTS_N_INSNS (32), /* DEBR */ ++ COSTS_N_INSNS (160), /* DLGR */ ++ COSTS_N_INSNS (71), /* DLR */ ++ COSTS_N_INSNS (71), /* DR */ ++ COSTS_N_INSNS (71), /* DSGFR */ ++ COSTS_N_INSNS (71), /* DSGR */ ++}; ++ + extern int reload_completed; + + /* Save information from a "cmpxx" operation until the branch or scc is +@@ -1029,6 +1062,41 @@ + } + } + ++ ++/* Return branch condition mask to implement a compare and branch ++ specified by CODE. Return -1 for invalid comparisons. */ ++ ++int ++s390_compare_and_branch_condition_mask (rtx code) ++{ ++ const int CC0 = 1 << 3; ++ const int CC1 = 1 << 2; ++ const int CC2 = 1 << 1; ++ ++ switch (GET_CODE (code)) ++ { ++ case EQ: ++ return CC0; ++ case NE: ++ return CC1 | CC2; ++ case LT: ++ case LTU: ++ return CC1; ++ case GT: ++ case GTU: ++ return CC2; ++ case LE: ++ case LEU: ++ return CC0 | CC1; ++ case GE: ++ case GEU: ++ return CC0 | CC2; ++ default: ++ gcc_unreachable (); ++ } ++ return -1; ++} ++ + /* If INV is false, return assembler mnemonic string to implement + a branch specified by CODE. If INV is true, return mnemonic + for the corresponding inverted branch. */ +@@ -1036,6 +1104,8 @@ + static const char * + s390_branch_condition_mnemonic (rtx code, int inv) + { ++ int mask; ++ + static const char *const mnemonic[16] = + { + NULL, "o", "h", "nle", +@@ -1044,7 +1114,13 @@ + "le", "nh", "no", NULL + }; + +- int mask = s390_branch_condition_mask (code); ++ if (GET_CODE (XEXP (code, 0)) == REG ++ && REGNO (XEXP (code, 0)) == CC_REGNUM ++ && XEXP (code, 1) == const0_rtx) ++ mask = s390_branch_condition_mask (code); ++ else ++ mask = s390_compare_and_branch_condition_mask (code); ++ + gcc_assert (mask >= 0); + + if (inv) +@@ -1121,6 +1197,67 @@ + return part == -1 ? -1 : n_parts - 1 - part; + } + ++/* Return true if IN contains a contiguous bitfield in the lower SIZE ++ bits and no other bits are set in IN. POS and LENGTH can be used ++ to obtain the start position and the length of the bitfield. ++ ++ POS gives the position of the first bit of the bitfield counting ++ from the lowest order bit starting with zero. In order to use this ++ value for S/390 instructions this has to be converted to "bits big ++ endian" style. */ ++ ++bool ++s390_contiguous_bitmask_p (unsigned HOST_WIDE_INT in, int size, ++ int *pos, int *length) ++{ ++ int tmp_pos = 0; ++ int tmp_length = 0; ++ int i; ++ unsigned HOST_WIDE_INT mask = 1ULL; ++ bool contiguous = false; ++ ++ for (i = 0; i < size; mask <<= 1, i++) ++ { ++ if (contiguous) ++ { ++ if (mask & in) ++ tmp_length++; ++ else ++ break; ++ } ++ else ++ { ++ if (mask & in) ++ { ++ contiguous = true; ++ tmp_length++; ++ } ++ else ++ tmp_pos++; ++ } ++ } ++ ++ if (!tmp_length) ++ return false; ++ ++ /* Calculate a mask for all bits beyond the contiguous bits. */ ++ mask = (-1LL & ~(((1ULL << (tmp_length + tmp_pos - 1)) << 1) - 1)); ++ ++ if (mask & in) ++ return false; ++ ++ if (tmp_length + tmp_pos - 1 > size) ++ return false; ++ ++ if (length) ++ *length = tmp_length; ++ ++ if (pos) ++ *pos = tmp_pos; ++ ++ return true; ++} ++ + /* Check whether we can (and want to) split a double-word + move in mode MODE from SRC to DST into two single-word + moves, moving the subword FIRST_SUBWORD first. */ +@@ -1365,6 +1502,8 @@ + | PF_LONG_DISPLACEMENT | PF_EXTIMM}, + {"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}, + }; + size_t i; + +@@ -1472,13 +1611,21 @@ + } + + /* Set processor cost function. */ +- if (s390_tune == PROCESSOR_2094_Z9_109) +- s390_cost = &z9_109_cost; +- else if (s390_tune == PROCESSOR_2084_Z990) +- s390_cost = &z990_cost; +- else +- s390_cost = &z900_cost; +- ++ switch (s390_tune) ++ { ++ case PROCESSOR_2084_Z990: ++ s390_cost = &z990_cost; ++ break; ++ case PROCESSOR_2094_Z9_109: ++ s390_cost = &z9_109_cost; ++ break; ++ case PROCESSOR_2097_Z10: ++ s390_cost = &z10_cost; ++ break; ++ default: ++ s390_cost = &z900_cost; ++ } ++ + if (TARGET_BACKCHAIN && TARGET_PACKED_STACK && TARGET_HARD_FLOAT) + error ("-mbackchain -mpacked-stack -mhard-float are not supported " + "in combination"); +@@ -1992,11 +2139,10 @@ + return 0; + if (GET_CODE (op) != MEM) + return 0; +- /* Any invalid address here will be fixed up by reload, +- so accept it for the most generic constraint. */ +- if (s390_decompose_address (XEXP (op, 0), &addr) +- && s390_short_displacement (addr.disp)) ++ if (!s390_decompose_address (XEXP (op, 0), &addr)) + return 0; ++ if (s390_short_displacement (addr.disp)) ++ return 0; + break; + + case 'U': +@@ -2012,11 +2158,10 @@ + case 'W': + if (!TARGET_LONG_DISPLACEMENT) + return 0; +- /* Any invalid address here will be fixed up by reload, +- so accept it for the most generic constraint. */ +- if (s390_decompose_address (op, &addr) +- && s390_short_displacement (addr.disp)) ++ if (!s390_decompose_address (op, &addr)) + return 0; ++ if (s390_short_displacement (addr.disp)) ++ return 0; + break; + + case 'Y': +@@ -2651,6 +2796,132 @@ + return class; + } + ++/* Return true if ADDR is of kind symbol_ref or symbol_ref + const_int ++ and return these parts in SYMREF and ADDEND. You can pass NULL in ++ SYMREF and/or ADDEND if you are not interested in these values. */ ++ ++static bool ++s390_symref_operand_p (rtx addr, rtx *symref, HOST_WIDE_INT *addend) ++{ ++ HOST_WIDE_INT tmpaddend = 0; ++ ++ if (GET_CODE (addr) == CONST) ++ addr = XEXP (addr, 0); ++ ++ if (GET_CODE (addr) == PLUS) ++ { ++ if (GET_CODE (XEXP (addr, 0)) == SYMBOL_REF ++ && CONST_INT_P (XEXP (addr, 1))) ++ { ++ tmpaddend = INTVAL (XEXP (addr, 1)); ++ addr = XEXP (addr, 0); ++ } ++ else ++ return false; ++ } ++ else ++ if (GET_CODE (addr) != SYMBOL_REF) ++ return false; ++ ++ if (symref) ++ *symref = addr; ++ if (addend) ++ *addend = tmpaddend; ++ ++ return true; ++} ++ ++/* Return true if ADDR is SYMBOL_REF + addend with addend being a ++ multiple of ALIGNMENT and the SYMBOL_REF being naturally ++ aligned. */ ++ ++bool ++s390_check_symref_alignment (rtx addr, HOST_WIDE_INT alignment) ++{ ++ HOST_WIDE_INT addend; ++ rtx symref; ++ ++ if (!s390_symref_operand_p (addr, &symref, &addend)) ++ return false; ++ ++ return (!SYMBOL_REF_NOT_NATURALLY_ALIGNED_P (symref) ++ && !(addend & (alignment - 1))); ++} ++ ++/* ADDR is moved into REG using larl. If ADDR isn't a valid larl ++ operand SCRATCH is used to reload the even part of the address and ++ adding one. */ ++ ++void ++s390_reload_larl_operand (rtx reg, rtx addr, rtx scratch) ++{ ++ HOST_WIDE_INT addend; ++ rtx symref; ++ ++ if (!s390_symref_operand_p (addr, &symref, &addend)) ++ gcc_unreachable (); ++ ++ if (!(addend & 1)) ++ /* Easy case. The addend is even so larl will do fine. */ ++ emit_move_insn (reg, addr); ++ else ++ { ++ /* We can leave the scratch register untouched if the target ++ register is a valid base register. */ ++ if (REGNO (reg) < FIRST_PSEUDO_REGISTER ++ && REGNO_REG_CLASS (REGNO (reg)) == ADDR_REGS) ++ scratch = reg; ++ ++ gcc_assert (REGNO (scratch) < FIRST_PSEUDO_REGISTER); ++ gcc_assert (REGNO_REG_CLASS (REGNO (scratch)) == ADDR_REGS); ++ ++ if (addend != 1) ++ emit_move_insn (scratch, ++ gen_rtx_CONST (Pmode, ++ gen_rtx_PLUS (Pmode, symref, ++ GEN_INT (addend - 1)))); ++ else ++ emit_move_insn (scratch, symref); ++ ++ /* Increment the address using la in order to avoid clobbering cc. */ ++ emit_move_insn (reg, gen_rtx_PLUS (Pmode, scratch, const1_rtx)); ++ } ++} ++ ++/* Generate what is necessary to move between REG and MEM using ++ SCRATCH. The direction is given by TOMEM. */ ++ ++void ++s390_reload_symref_address (rtx reg, rtx mem, rtx scratch, bool tomem) ++{ ++ /* Reload might have pulled a constant out of the literal pool. ++ Force it back in. */ ++ if (CONST_INT_P (mem) || GET_CODE (mem) == CONST_DOUBLE ++ || GET_CODE (mem) == CONST) ++ mem = force_const_mem (GET_MODE (reg), mem); ++ ++ gcc_assert (MEM_P (mem)); ++ ++ /* For a load from memory we can leave the scratch register ++ untouched if the target register is a valid base register. */ ++ if (!tomem ++ && REGNO (reg) < FIRST_PSEUDO_REGISTER ++ && REGNO_REG_CLASS (REGNO (reg)) == ADDR_REGS ++ && GET_MODE (reg) == GET_MODE (scratch)) ++ scratch = reg; ++ ++ /* Load address into scratch register. Since we can't have a ++ secondary reload for a secondary reload we have to cover the case ++ where larl would need a secondary reload here as well. */ ++ s390_reload_larl_operand (scratch, XEXP (mem, 0), scratch); ++ ++ /* Now we can use a standard load/store to do the move. */ ++ if (tomem) ++ emit_move_insn (replace_equiv_address (mem, scratch), reg); ++ else ++ emit_move_insn (reg, replace_equiv_address (mem, scratch)); ++} ++ + /* Inform reload about cases where moving X with a mode MODE to a register in + CLASS requires an extra scratch or immediate register. Return the class + needed for the immediate register. */ +@@ -2663,6 +2934,60 @@ + if (reg_classes_intersect_p (CC_REGS, class)) + return GENERAL_REGS; + ++ if (TARGET_Z10) ++ { ++ /* On z10 several optimizer steps may generate larl operands with ++ an odd addend. */ ++ if (in_p ++ && s390_symref_operand_p (x, NULL, NULL) ++ && mode == Pmode ++ && !s390_check_symref_alignment (x, 2)) ++ sri->icode = ((mode == DImode) ? CODE_FOR_reloaddi_larl_odd_addend_z10 ++ : CODE_FOR_reloadsi_larl_odd_addend_z10); ++ ++ /* On z10 we need a scratch register when moving QI, TI or floating ++ point mode values from or to a memory location with a SYMBOL_REF ++ or if the symref addend of a SI or DI move is not aligned to the ++ width of the access. */ ++ if (MEM_P (x) ++ && s390_symref_operand_p (XEXP (x, 0), NULL, NULL) ++ && (mode == QImode || mode == TImode || FLOAT_MODE_P (mode) ++ || (!TARGET_64BIT && mode == DImode) ++ || ((mode == HImode || mode == SImode || mode == DImode) ++ && (!s390_check_symref_alignment (XEXP (x, 0), ++ GET_MODE_SIZE (mode)))))) ++ { ++#define __SECONDARY_RELOAD_CASE(M,m) \ ++ case M##mode: \ ++ if (TARGET_64BIT) \ ++ sri->icode = in_p ? CODE_FOR_reload##m##di_toreg_z10 : \ ++ CODE_FOR_reload##m##di_tomem_z10; \ ++ else \ ++ sri->icode = in_p ? CODE_FOR_reload##m##si_toreg_z10 : \ ++ CODE_FOR_reload##m##si_tomem_z10; \ ++ break; ++ ++ switch (GET_MODE (x)) ++ { ++ __SECONDARY_RELOAD_CASE (QI, qi); ++ __SECONDARY_RELOAD_CASE (HI, hi); ++ __SECONDARY_RELOAD_CASE (SI, si); ++ __SECONDARY_RELOAD_CASE (DI, di); ++ __SECONDARY_RELOAD_CASE (TI, ti); ++ __SECONDARY_RELOAD_CASE (SF, sf); ++ __SECONDARY_RELOAD_CASE (DF, df); ++ __SECONDARY_RELOAD_CASE (TF, tf); ++ __SECONDARY_RELOAD_CASE (SD, sd); ++ __SECONDARY_RELOAD_CASE (DD, dd); ++ __SECONDARY_RELOAD_CASE (TD, td); ++ ++ default: ++ gcc_unreachable (); ++ } ++#undef __SECONDARY_RELOAD_CASE ++ } ++ } ++ + /* We need a scratch register when loading a PLUS expression which + is not a legitimate operand of the LOAD ADDRESS instruction. */ + if (in_p && s390_plus_operand (x, mode)) +@@ -2769,10 +3094,16 @@ + STRICT specifies whether strict register checking applies. */ + + bool +-legitimate_address_p (enum machine_mode mode ATTRIBUTE_UNUSED, +- rtx addr, int strict) ++legitimate_address_p (enum machine_mode mode, rtx addr, int strict) + { + struct s390_address ad; ++ ++ if (TARGET_Z10 ++ && larl_operand (addr, VOIDmode) ++ && (mode == VOIDmode ++ || s390_check_symref_alignment (addr, GET_MODE_SIZE (mode)))) ++ return true; ++ + if (!s390_decompose_address (addr, &ad)) + return false; + +@@ -4010,14 +4341,31 @@ + return false; + } + +-/* Expand code for the insv template. Return true if successful, false else. */ ++/* Expand code for the insv template. Return true if successful. */ + +-bool ++bool + s390_expand_insv (rtx dest, rtx op1, rtx op2, rtx src) + { + int bitsize = INTVAL (op1); + int bitpos = INTVAL (op2); + ++ /* On z10 we can use the risbg instruction to implement insv. */ ++ if (TARGET_Z10 ++ && ((GET_MODE (dest) == DImode && GET_MODE (src) == DImode) ++ || (GET_MODE (dest) == SImode && GET_MODE (src) == SImode))) ++ { ++ rtx op; ++ rtx clobber; ++ ++ op = gen_rtx_SET (GET_MODE(src), ++ gen_rtx_ZERO_EXTRACT (GET_MODE (dest), dest, op1, op2), ++ src); ++ clobber = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM)); ++ emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clobber))); ++ ++ return true; ++ } ++ + /* We need byte alignment. */ + if (bitsize % BITS_PER_UNIT) + return false; +@@ -4554,6 +4902,13 @@ + { + struct s390_address ad; + ++ if (s390_symref_operand_p (addr, NULL, NULL)) ++ { ++ gcc_assert (TARGET_Z10); ++ output_addr_const (file, addr); ++ return; ++ } ++ + if (!s390_decompose_address (addr, &ad) + || (ad.base && !REGNO_OK_FOR_BASE_P (REGNO (ad.base))) + || (ad.indx && !REGNO_OK_FOR_INDEX_P (REGNO (ad.indx)))) +@@ -4587,6 +4942,7 @@ + 'Y': print shift count operand. + + 'b': print integer X as if it's an unsigned byte. ++ 'c': print integer X as if it's an signed byte. + 'x': print integer X as if it's an unsigned halfword. + 'h': print integer X as if it's a signed halfword. + 'i': print the first nonzero HImode part of X. +@@ -4732,6 +5088,8 @@ + case CONST_INT: + if (code == 'b') + fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xff); ++ else if (code == 'c') ++ fprintf (file, HOST_WIDE_INT_PRINT_DEC, ((INTVAL (x) & 0xff) ^ 0x80) - 0x80); + else if (code == 'x') + fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0xffff); + else if (code == 'h') +@@ -4891,6 +5249,7 @@ + return 0; + } + ++ + /* A C statement (sans semicolon) to update the integer scheduling priority + INSN_PRIORITY (INSN). Increase the priority to execute the INSN earlier, + reduce the priority to execute INSN later. Do not define this macro if +@@ -4930,10 +5289,16 @@ + static int + s390_issue_rate (void) + { +- if (s390_tune == PROCESSOR_2084_Z990 +- || s390_tune == PROCESSOR_2094_Z9_109) +- return 3; +- return 1; ++ switch (s390_tune) ++ { ++ case PROCESSOR_2084_Z990: ++ case PROCESSOR_2094_Z9_109: ++ return 3; ++ case PROCESSOR_2097_Z10: ++ return 2; ++ default: ++ return 1; ++ } + } + + static int +@@ -8515,11 +8880,30 @@ + { + default_encode_section_info (decl, rtl, first); + +- /* If a variable has a forced alignment to < 2 bytes, mark it with +- SYMBOL_FLAG_ALIGN1 to prevent it from being used as LARL operand. */ +- if (TREE_CODE (decl) == VAR_DECL +- && DECL_USER_ALIGN (decl) && DECL_ALIGN (decl) < 16) +- SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_ALIGN1; ++ if (TREE_CODE (decl) == VAR_DECL) ++ { ++ /* If a variable has a forced alignment to < 2 bytes, mark it ++ with SYMBOL_FLAG_ALIGN1 to prevent it from being used as LARL ++ operand. */ ++ if (DECL_USER_ALIGN (decl) && DECL_ALIGN (decl) < 16) ++ SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_ALIGN1; ++ if (!DECL_SIZE (decl) ++ || !DECL_ALIGN (decl) ++ || !host_integerp (DECL_SIZE (decl), 0) ++ || (DECL_ALIGN (decl) <= 64 ++ && DECL_ALIGN (decl) != tree_low_cst (DECL_SIZE (decl), 0))) ++ SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_NOT_NATURALLY_ALIGNED; ++ } ++ ++ /* Literal pool references don't have a decl so they are handled ++ differently here. We rely on the information in the MEM_ALIGN ++ entry to decide upon natural alignment. */ ++ if (MEM_P (rtl) ++ && GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF ++ && TREE_CONSTANT_POOL_ADDRESS_P (XEXP (rtl, 0)) ++ && (MEM_ALIGN (rtl) == 0 ++ || MEM_ALIGN (rtl) < GET_MODE_BITSIZE (GET_MODE (rtl)))) ++ SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= SYMBOL_FLAG_NOT_NATURALLY_ALIGNED; + } + + /* Output thunk to FILE that implements a C++ virtual function call (with +Index: gcc/config/s390/predicates.md +=================================================================== +--- gcc/config/s390/predicates.md (revision 141434) ++++ gcc/config/s390/predicates.md (working copy) +@@ -1,5 +1,5 @@ + ;; Predicate definitions for S/390 and zSeries. +-;; Copyright (C) 2005, 2007 Free Software Foundation, Inc. ++;; Copyright (C) 2005, 2007, 2008 Free Software Foundation, Inc. + ;; Contributed by Hartmut Penner (hpenner@de.ibm.com) and + ;; Ulrich Weigand (uweigand@de.ibm.com). + ;; +@@ -110,7 +110,7 @@ + if (GET_CODE (op) == LABEL_REF) + return true; + if (GET_CODE (op) == SYMBOL_REF) +- return ((SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_ALIGN1) == 0 ++ return (!SYMBOL_REF_ALIGN1_P (op) + && SYMBOL_REF_TLS_MODEL (op) == 0 + && (!flag_pic || SYMBOL_REF_LOCAL_P (op))); + +@@ -172,6 +172,18 @@ + return (s390_branch_condition_mask (op) >= 0); + }) + ++(define_predicate "s390_signed_integer_comparison" ++ (match_code "eq, ne, lt, gt, le, ge") ++{ ++ return (s390_compare_and_branch_condition_mask (op) >= 0); ++}) ++ ++(define_predicate "s390_unsigned_integer_comparison" ++ (match_code "eq, ne, ltu, gtu, leu, geu") ++{ ++ return (s390_compare_and_branch_condition_mask (op) >= 0); ++}) ++ + ;; Return nonzero if OP is a valid comparison operator + ;; for an ALC condition. + +Index: gcc/config/s390/s390.h +=================================================================== +--- gcc/config/s390/s390.h (revision 141434) ++++ gcc/config/s390/s390.h (working copy) +@@ -1,8 +1,9 @@ + /* Definitions of target machine for GNU compiler, for IBM S/390 + Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, +- 2007 Free Software Foundation, Inc. ++ 2007, 2008 Free Software Foundation, Inc. + Contributed by Hartmut Penner (hpenner@de.ibm.com) and + Ulrich Weigand (uweigand@de.ibm.com). ++ Andreas Krebbel (Andreas.Krebbel@de.ibm.com) + + This file is part of GCC. + +@@ -40,6 +41,7 @@ + PROCESSOR_2064_Z900, + PROCESSOR_2084_Z990, + PROCESSOR_2094_Z9_109, ++ PROCESSOR_2097_Z10, + PROCESSOR_max + }; + +@@ -51,7 +53,8 @@ + PF_ZARCH = 2, + PF_LONG_DISPLACEMENT = 4, + PF_EXTIMM = 8, +- PF_DFP = 16 ++ PF_DFP = 16, ++ PF_Z10 = 32 + }; + + extern enum processor_type s390_tune; +@@ -60,6 +63,10 @@ + extern enum processor_type s390_arch; + extern enum processor_flags s390_arch_flags; + ++/* These flags indicate that the generated code should run on a cpu ++ providing the respective hardware facility regardless of the ++ current cpu mode (ESA or z/Architecture). */ ++ + #define TARGET_CPU_IEEE_FLOAT \ + (s390_arch_flags & PF_IEEE_FLOAT) + #define TARGET_CPU_ZARCH \ +@@ -70,13 +77,21 @@ + (s390_arch_flags & PF_EXTIMM) + #define TARGET_CPU_DFP \ + (s390_arch_flags & PF_DFP) ++#define TARGET_CPU_Z10 \ ++ (s390_arch_flags & PF_Z10) + ++/* These flags indicate that the generated code should run on a cpu ++ providing the respective hardware facility when run in ++ z/Architecture mode. */ ++ + #define TARGET_LONG_DISPLACEMENT \ + (TARGET_ZARCH && TARGET_CPU_LONG_DISPLACEMENT) + #define TARGET_EXTIMM \ + (TARGET_ZARCH && TARGET_CPU_EXTIMM) + #define TARGET_DFP \ +- (TARGET_ZARCH && TARGET_CPU_DFP) ++ (TARGET_ZARCH && TARGET_CPU_DFP && TARGET_HARD_FLOAT) ++#define TARGET_Z10 \ ++ (TARGET_ZARCH && TARGET_CPU_Z10) + + /* Run-time target specification. */ + +@@ -485,11 +500,14 @@ + #define PREFERRED_RELOAD_CLASS(X, CLASS) \ + s390_preferred_reload_class ((X), (CLASS)) + +-/* We need secondary memory to move data between GPRs and FPRs. */ ++/* We need secondary memory to move data between GPRs and FPRs. With ++ DFP the ldgr lgdr instructions are available. But these ++ instructions do not handle GPR pairs so it is not possible for 31 ++ bit. */ + #define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \ + ((CLASS1) != (CLASS2) \ + && ((CLASS1) == FP_REGS || (CLASS2) == FP_REGS) \ +- && (!TARGET_DFP || GET_MODE_SIZE (MODE) != 8)) ++ && (!TARGET_DFP || !TARGET_64BIT || GET_MODE_SIZE (MODE) != 8)) + + /* Get_secondary_mem widens its argument to BITS_PER_WORD which loses on 64bit + because the movsi and movsf patterns don't handle r/f moves. */ +@@ -688,6 +706,13 @@ + /* Maximum number of registers that can appear in a valid memory address. */ + #define MAX_REGS_PER_ADDRESS 2 + ++/* This definition replaces the formerly used 'm' constraint with a ++different constraint letter in order to avoid changing semantics of ++the 'm' constraint when accepting new address formats in ++legitimate_address_p. The constraint letter defined here must not be ++used in insn definitions or inline assemblies. */ ++#define TARGET_MEM_CONSTRAINT 'e' ++ + /* S/390 has no mode dependent addresses. */ + #define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) + +@@ -954,7 +979,12 @@ + #define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) ((VALUE) = 64, 1) + + /* Machine-specific symbol_ref flags. */ +-#define SYMBOL_FLAG_ALIGN1 (SYMBOL_FLAG_MACH_DEP << 0) ++#define SYMBOL_FLAG_ALIGN1 (SYMBOL_FLAG_MACH_DEP << 0) ++#define SYMBOL_REF_ALIGN1_P(X) \ ++ ((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_ALIGN1)) ++#define SYMBOL_FLAG_NOT_NATURALLY_ALIGNED (SYMBOL_FLAG_MACH_DEP << 1) ++#define SYMBOL_REF_NOT_NATURALLY_ALIGNED_P(X) \ ++ ((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_NOT_NATURALLY_ALIGNED)) + + /* Check whether integer displacement is in range. */ + #define DISP_IN_RANGE(d) \ +Index: gcc/config/s390/2084.md +=================================================================== +--- gcc/config/s390/2084.md (revision 141434) ++++ gcc/config/s390/2084.md (working copy) +@@ -243,7 +243,7 @@ + + (define_insn_reservation "x_itof" 7 + (and (eq_attr "cpu" "z990,z9_109") +- (eq_attr "type" "itof")) ++ (eq_attr "type" "itoftf,itofdf,itofsf")) + "x_e1_t*3,x-wr-fp") + + (define_bypass 1 "x_fsimpdf" "x_fstoredf") +Index: gcc/config/s390/s390.md +=================================================================== +--- gcc/config/s390/s390.md (revision 141434) ++++ gcc/config/s390/s390.md (working copy) +@@ -1,8 +1,9 @@ + ;;- Machine description for GNU compiler -- S/390 / zSeries version. +-;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 ++;; Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 + ;; Free Software Foundation, Inc. + ;; Contributed by Hartmut Penner (hpenner@de.ibm.com) and +-;; Ulrich Weigand (uweigand@de.ibm.com). ++;; Ulrich Weigand (uweigand@de.ibm.com) and ++;; Andreas Krebbel (Andreas.Krebbel@de.ibm.com) + + ;; This file is part of GCC. + +@@ -38,6 +39,7 @@ + ;; %Y: print shift count operand. + ;; + ;; %b: print integer X as if it's an unsigned byte. ++;; %c: print integer X as if it's an signed byte. + ;; %x: print integer X as if it's an unsigned halfword. + ;; %h: print integer X as if it's a signed halfword. + ;; %i: print the first nonzero HImode part of X. +@@ -189,7 +191,7 @@ + ;; Used to determine defaults for length and other attribute values. + + (define_attr "op_type" +- "NN,E,RR,RRE,RX,RS,RSI,RI,SI,S,SS,SSE,RXE,RSE,RIL,RIE,RXY,RSY,SIY,RRF,RRR" ++ "NN,E,RR,RRE,RX,RS,RSI,RI,SI,S,SS,SSE,RXE,RSE,RIL,RIE,RXY,RSY,SIY,RRF,RRR,SIL,RRS,RIS" + (const_string "NN")) + + ;; Instruction type attribute used for scheduling. +@@ -200,8 +202,12 @@ + branch,jsr,fsimptf,fsimpdf,fsimpsf, + floadtf,floaddf,floadsf,fstoredf,fstoresf, + fmultf,fmuldf,fmulsf,fdivtf,fdivdf,fdivsf, +- ftoi,itof,fsqrttf,fsqrtdf,fsqrtsf, +- ftrunctf,ftruncdf,other" ++ ftoi,fsqrttf,fsqrtdf,fsqrtsf, ++ ftrunctf,ftruncdf, ftruncsd, ftruncdd, ++ itoftf, itofdf, itofsf, itofdd, itoftd, ++ fdivdd, fdivtd, floaddd, floadsd, fmuldd, fmultd, ++ fsimpdd, fsimpsd, fsimptd, fstoredd, fstoresd, ++ ftoidfp, other" + (cond [(eq_attr "op_type" "NN") (const_string "other") + (eq_attr "op_type" "SS") (const_string "cs")] + (const_string "integer"))) +@@ -215,11 +221,36 @@ + (const_string "reg") + (const_string "agen"))) + ++;; Properties concerning Z10 execution grouping and value forwarding. ++;; z10_super: instruction is superscalar. ++;; z10_super_c: instruction is superscalar and meets the condition of z10_c. ++;; z10_fwd: The instruction reads the value of an operand and stores it into a ++;; target register. It can forward this value to a second instruction that reads ++;; the same register if that second instruction is issued in the same group. ++;; z10_rec: The instruction is in the T pipeline and reads a register. If the ++;; instruction in the S pipe writes to the register, then the T instruction ++;; can immediately read the new value. ++;; z10_fr: union of Z10_fwd and z10_rec. ++;; z10_c: second operand of instruction is a register and read with complemented bits. ++;; z10_cobra: its a compare and branch instruction ++;; ++;; An additional suffix A1, A3, or E1 indicates the respective AGI bypass. ++ ++ ++(define_attr "z10prop" "none, ++ z10_super, z10_super_E1, z10_super_A1, z10_super_c, z10_super_c_E1, ++ z10_fwd, z10_fwd_A1, z10_fwd_A3, z10_fwd_E1, ++ z10_rec, ++ z10_fr, z10_fr_A3, z10_fr_E1, ++ z10_c, z10_cobra" ++ (const_string "none")) ++ ++ + ;; Length in bytes. + + (define_attr "length" "" +- (cond [(eq_attr "op_type" "E,RR") (const_int 2) +- (eq_attr "op_type" "RX,RI,RRE,RS,RSI,S,SI") (const_int 4)] ++ (cond [(eq_attr "op_type" "E,RR") (const_int 2) ++ (eq_attr "op_type" "RX,RI,RRE,RS,RSI,S,SI,RRF,RRR") (const_int 4)] + (const_int 6))) + + +@@ -228,9 +259,41 @@ + ;; 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" ++(define_attr "cpu" "g5,g6,z900,z990,z9_109,z10" + (const (symbol_ref "s390_tune"))) + ++(define_attr "cpu_facility" "standard,ieee,zarch,longdisp,extimm,dfp,z10" ++ (const_string "standard")) ++ ++(define_attr "enabled" "" ++ (cond [(eq_attr "cpu_facility" "standard") ++ (const_int 1) ++ ++ (and (eq_attr "cpu_facility" "ieee") ++ (ne (symbol_ref "TARGET_CPU_IEEE_FLOAT") (const_int 0))) ++ (const_int 1) ++ ++ (and (eq_attr "cpu_facility" "zarch") ++ (ne (symbol_ref "TARGET_ZARCH") (const_int 0))) ++ (const_int 1) ++ ++ (and (eq_attr "cpu_facility" "longdisp") ++ (ne (symbol_ref "TARGET_LONG_DISPLACEMENT") (const_int 0))) ++ (const_int 1) ++ ++ (and (eq_attr "cpu_facility" "extimm") ++ (ne (symbol_ref "TARGET_EXTIMM") (const_int 0))) ++ (const_int 1) ++ ++ (and (eq_attr "cpu_facility" "dfp") ++ (ne (symbol_ref "TARGET_DFP") (const_int 0))) ++ (const_int 1) ++ ++ (and (eq_attr "cpu_facility" "z10") ++ (ne (symbol_ref "TARGET_Z10") (const_int 0))) ++ (const_int 1)] ++ (const_int 0))) ++ + ;; Pipeline description for z900. For lack of anything better, + ;; this description is also used for the g5 and g6. + (include "2064.md") +@@ -238,6 +301,9 @@ + ;; Pipeline description for z990, z9-109 and z9-ec. + (include "2084.md") + ++;; Pipeline description for z10 ++(include "2097.md") ++ + ;; Predicates + (include "predicates.md") + +@@ -254,6 +320,7 @@ + (define_mode_iterator FP_ALL [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP") + (SD "TARGET_HARD_DFP")]) + (define_mode_iterator FP [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")]) ++(define_mode_iterator FPALL [TF DF SF TD DD SD]) + (define_mode_iterator BFP [TF DF SF]) + (define_mode_iterator DFP [TD DD]) + (define_mode_iterator DFP_ALL [TD DD SD]) +@@ -283,6 +350,7 @@ + ;; This mode iterator allows the integer patterns to be defined from the + ;; same template. + (define_mode_iterator INT [(DI "TARGET_64BIT") SI HI QI]) ++(define_mode_iterator INTALL [TI DI SI HI QI]) + + ;; This iterator allows to unify all 'bCOND' expander patterns. + (define_code_iterator COMPARE [eq ne gt gtu lt ltu ge geu le leu unordered +@@ -352,12 +420,6 @@ + ;; modes and to an empty string for bfp modes. + (define_mode_attr _d [(TF "") (DF "") (SF "") (TD "d") (DD "d") (SD "d")]) + +-;; Although it is imprecise for z9-ec we handle all dfp instructions like +-;; bfp regarding the pipeline description. +-(define_mode_attr bfp [(TF "tf") (DF "df") (SF "sf") +- (TD "tf") (DD "df") (SD "sf")]) +- +- + ;; In GPR and P templates, a constraint like "<d0>" will expand to "d" in DImode + ;; and "0" in SImode. This allows to combine instructions of which the 31bit + ;; version only operates on one register. +@@ -367,13 +429,13 @@ + ;; version only operates on one register. The DImode version needs an additional + ;; register for the assembler output. + (define_mode_attr 1 [(DI "%1,") (SI "")]) +- +-;; In SHIFT templates, a string like "s<lr>dl" will expand to "sldl" in ++ ++;; In SHIFT templates, a string like "s<lr>dl" will expand to "sldl" in + ;; 'ashift' and "srdl" in 'lshiftrt'. + (define_code_attr lr [(ashift "l") (lshiftrt "r")]) + + ;; In SHIFT templates, this attribute holds the correct standard name for the +-;; pattern itself and the corresponding function calls. ++;; pattern itself and the corresponding function calls. + (define_code_attr shift [(ashift "ashl") (lshiftrt "lshr")]) + + ;; This attribute handles differences in the instruction 'type' and will result +@@ -425,7 +487,6 @@ + ;; Maximum unsigned integer that fits in MODE. + (define_mode_attr max_uint [(HI "65535") (QI "255")]) + +- + ;; + ;;- Compare instructions. + ;; +@@ -464,7 +525,8 @@ + "@ + tm\t%S0,%b1 + tmy\t%S0,%b1" +- [(set_attr "op_type" "SI,SIY")]) ++ [(set_attr "op_type" "SI,SIY") ++ (set_attr "z10prop" "z10_super,z10_super")]) + + (define_insn "*tmdi_reg" + [(set (reg CC_REGNUM) +@@ -480,7 +542,8 @@ + tmhl\t%0,%i1 + tmlh\t%0,%i1 + tmll\t%0,%i1" +- [(set_attr "op_type" "RI")]) ++ [(set_attr "op_type" "RI") ++ (set_attr "z10prop" "z10_super,z10_super,z10_super,z10_super")]) + + (define_insn "*tmsi_reg" + [(set (reg CC_REGNUM) +@@ -511,19 +574,25 @@ + + (define_insn "*tstdi_sign" + [(set (reg CC_REGNUM) +- (compare (ashiftrt:DI (ashift:DI (subreg:DI (match_operand:SI 0 "register_operand" "d") 0) +- (const_int 32)) (const_int 32)) +- (match_operand:DI 1 "const0_operand" ""))) +- (set (match_operand:DI 2 "register_operand" "=d") ++ (compare ++ (ashiftrt:DI ++ (ashift:DI ++ (subreg:DI (match_operand:SI 0 "nonimmediate_operand" "d,RT") 0) ++ (const_int 32)) (const_int 32)) ++ (match_operand:DI 1 "const0_operand" ""))) ++ (set (match_operand:DI 2 "register_operand" "=d,d") + (sign_extend:DI (match_dup 0)))] + "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT" +- "ltgfr\t%2,%0" +- [(set_attr "op_type" "RRE")]) ++ "ltgfr\t%2,%0 ++ ltgf\t%2,%0" ++ [(set_attr "op_type" "RRE,RXY") ++ (set_attr "cpu_facility" "*,z10") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1") ]) + + ; ltr, lt, ltgr, ltg + (define_insn "*tst<mode>_extimm" + [(set (reg CC_REGNUM) +- (compare (match_operand:GPR 0 "nonimmediate_operand" "d,m") ++ (compare (match_operand:GPR 0 "nonimmediate_operand" "d,RT") + (match_operand:GPR 1 "const0_operand" ""))) + (set (match_operand:GPR 2 "register_operand" "=d,d") + (match_dup 0))] +@@ -531,19 +600,21 @@ + "@ + lt<g>r\t%2,%0 + lt<g>\t%2,%0" +- [(set_attr "op_type" "RR<E>,RXY")]) ++ [(set_attr "op_type" "RR<E>,RXY") ++ (set_attr "z10prop" "z10_fr_E1,z10_fr_A3") ]) + + ; ltr, lt, ltgr, ltg + (define_insn "*tst<mode>_cconly_extimm" + [(set (reg CC_REGNUM) +- (compare (match_operand:GPR 0 "nonimmediate_operand" "d,m") ++ (compare (match_operand:GPR 0 "nonimmediate_operand" "d,RT") + (match_operand:GPR 1 "const0_operand" ""))) + (clobber (match_scratch:GPR 2 "=X,d"))] + "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM" + "@ + lt<g>r\t%0,%0 + lt<g>\t%2,%0" +- [(set_attr "op_type" "RR<E>,RXY")]) ++ [(set_attr "op_type" "RR<E>,RXY") ++ (set_attr "z10prop" "z10_fr_E1,z10_fr_A3")]) + + (define_insn "*tstdi" + [(set (reg CC_REGNUM) +@@ -553,7 +624,8 @@ + (match_dup 0))] + "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT && !TARGET_EXTIMM" + "ltgr\t%2,%0" +- [(set_attr "op_type" "RRE")]) ++ [(set_attr "op_type" "RRE") ++ (set_attr "z10prop" "z10_fr_E1")]) + + (define_insn "*tstsi" + [(set (reg CC_REGNUM) +@@ -566,7 +638,8 @@ + ltr\t%2,%0 + icm\t%2,15,%S0 + icmy\t%2,15,%S0" +- [(set_attr "op_type" "RR,RS,RSY")]) ++ [(set_attr "op_type" "RR,RS,RSY") ++ (set_attr "z10prop" "z10_fr_E1,z10_super_E1,z10_super_E1")]) + + (define_insn "*tstsi_cconly" + [(set (reg CC_REGNUM) +@@ -578,7 +651,8 @@ + ltr\t%0,%0 + icm\t%2,15,%S0 + icmy\t%2,15,%S0" +- [(set_attr "op_type" "RR,RS,RSY")]) ++ [(set_attr "op_type" "RR,RS,RSY") ++ (set_attr "z10prop" "z10_fr_E1,z10_super_E1,z10_super_E1")]) + + (define_insn "*tstdi_cconly_31" + [(set (reg CC_REGNUM) +@@ -596,7 +670,8 @@ + (match_operand:GPR 1 "const0_operand" "")))] + "s390_match_ccmode(insn, CCSmode)" + "lt<g>r\t%0,%0" +- [(set_attr "op_type" "RR<E>")]) ++ [(set_attr "op_type" "RR<E>") ++ (set_attr "z10prop" "z10_fr_E1")]) + + ; tst(hi|qi) instruction pattern(s). + +@@ -611,7 +686,8 @@ + icm\t%2,<icm_lo>,%S0 + icmy\t%2,<icm_lo>,%S0 + tml\t%0,<max_uint>" +- [(set_attr "op_type" "RS,RSY,RI")]) ++ [(set_attr "op_type" "RS,RSY,RI") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super")]) + + (define_insn "*tsthiCCT_cconly" + [(set (reg CC_REGNUM) +@@ -623,7 +699,8 @@ + icm\t%2,3,%S0 + icmy\t%2,3,%S0 + tml\t%0,65535" +- [(set_attr "op_type" "RS,RSY,RI")]) ++ [(set_attr "op_type" "RS,RSY,RI") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super")]) + + (define_insn "*tstqiCCT_cconly" + [(set (reg CC_REGNUM) +@@ -634,7 +711,8 @@ + cli\t%S0,0 + cliy\t%S0,0 + tml\t%0,255" +- [(set_attr "op_type" "SI,SIY,RI")]) ++ [(set_attr "op_type" "SI,SIY,RI") ++ (set_attr "z10prop" "z10_super,z10_super,*")]) + + (define_insn "*tst<mode>" + [(set (reg CC_REGNUM) +@@ -646,7 +724,8 @@ + "@ + icm\t%2,<icm_lo>,%S0 + icmy\t%2,<icm_lo>,%S0" +- [(set_attr "op_type" "RS,RSY")]) ++ [(set_attr "op_type" "RS,RSY") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1")]) + + (define_insn "*tst<mode>_cconly" + [(set (reg CC_REGNUM) +@@ -657,7 +736,8 @@ + "@ + icm\t%2,<icm_lo>,%S0 + icmy\t%2,<icm_lo>,%S0" +- [(set_attr "op_type" "RS,RSY")]) ++ [(set_attr "op_type" "RS,RSY") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1")]) + + + ; Compare (equality) instructions +@@ -665,7 +745,7 @@ + (define_insn "*cmpdi_cct" + [(set (reg CC_REGNUM) + (compare (match_operand:DI 0 "nonimmediate_operand" "%d,d,d,d,Q") +- (match_operand:DI 1 "general_operand" "d,K,Os,m,BQ")))] ++ (match_operand:DI 1 "general_operand" "d,K,Os,RT,BQ")))] + "s390_match_ccmode (insn, CCTmode) && TARGET_64BIT" + "@ + cgr\t%0,%1 +@@ -673,7 +753,8 @@ + cgfi\t%0,%1 + cg\t%0,%1 + #" +- [(set_attr "op_type" "RRE,RI,RIL,RXY,SS")]) ++ [(set_attr "op_type" "RRE,RI,RIL,RXY,SS") ++ (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,*")]) + + (define_insn "*cmpsi_cct" + [(set (reg CC_REGNUM) +@@ -687,97 +768,174 @@ + c\t%0,%1 + cy\t%0,%1 + #" +- [(set_attr "op_type" "RR,RI,RIL,RX,RXY,SS")]) ++ [(set_attr "op_type" "RR,RI,RIL,RX,RXY,SS") ++ (set_attr "z10prop" "z10_super,z10_super,z10_super,z10_super,z10_super,*")]) + +- + ; Compare (signed) instructions + + (define_insn "*cmpdi_ccs_sign" + [(set (reg CC_REGNUM) +- (compare (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m")) +- (match_operand:DI 0 "register_operand" "d,d")))] ++ (compare (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" ++ "d,RT,b")) ++ (match_operand:DI 0 "register_operand" "d, d,d")))] + "s390_match_ccmode(insn, CCSRmode) && TARGET_64BIT" + "@ + cgfr\t%0,%1 +- cgf\t%0,%1" +- [(set_attr "op_type" "RRE,RXY")]) ++ cgf\t%0,%1 ++ cgfrl\t%0,%1" ++ [(set_attr "op_type" "RRE,RXY,RIL") ++ (set_attr "z10prop" "z10_c,*,*") ++ (set_attr "type" "*,*,larl")]) + ++ ++ + (define_insn "*cmpsi_ccs_sign" + [(set (reg CC_REGNUM) +- (compare (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T")) +- (match_operand:SI 0 "register_operand" "d,d")))] ++ (compare (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T,b")) ++ (match_operand:SI 0 "register_operand" "d,d,d")))] + "s390_match_ccmode(insn, CCSRmode)" + "@ + ch\t%0,%1 +- chy\t%0,%1" +- [(set_attr "op_type" "RX,RXY")]) ++ chy\t%0,%1 ++ chrl\t%0,%1" ++ [(set_attr "op_type" "RX,RXY,RIL") ++ (set_attr "cpu_facility" "*,*,z10") ++ (set_attr "type" "*,*,larl")]) + +-; cr, chi, cfi, c, cy, cgr, cghi, cgfi, cg ++(define_insn "*cmphi_ccs_z10" ++ [(set (reg CC_REGNUM) ++ (compare (match_operand:HI 0 "s_operand" "Q") ++ (match_operand:HI 1 "immediate_operand" "K")))] ++ "s390_match_ccmode(insn, CCSmode) && TARGET_Z10" ++ "chhsi\t%0,%1" ++ [(set_attr "op_type" "SIL")]) ++ ++(define_insn "*cmpdi_ccs_signhi_rl" ++ [(set (reg CC_REGNUM) ++ (compare (sign_extend:DI (match_operand:HI 1 "memory_operand" "RT,b")) ++ (match_operand:GPR 0 "register_operand" "d,d")))] ++ "s390_match_ccmode(insn, CCSRmode) && TARGET_Z10" ++ "@ ++ cgh\t%0,%1 ++ cghrl\t%0,%1" ++ [(set_attr "op_type" "RXY,RIL") ++ (set_attr "type" "*,larl")]) ++ ++; cr, chi, cfi, c, cy, cgr, cghi, cgfi, cg, chsi, cghsi, crl, cgrl + (define_insn "*cmp<mode>_ccs" + [(set (reg CC_REGNUM) +- (compare (match_operand:GPR 0 "register_operand" "d,d,d,d,d") +- (match_operand:GPR 1 "general_operand" "d,K,Os,R,T")))] ++ (compare (match_operand:GPR 0 "nonimmediate_operand" ++ "d,d,Q, d,d,d,d") ++ (match_operand:GPR 1 "general_operand" ++ "d,K,K,Os,R,T,b")))] + "s390_match_ccmode(insn, CCSmode)" + "@ + c<g>r\t%0,%1 + c<g>hi\t%0,%h1 ++ c<g>hsi\t%0,%h1 + c<g>fi\t%0,%1 + c<g>\t%0,%1 +- c<y>\t%0,%1" +- [(set_attr "op_type" "RR<E>,RI,RIL,RX<Y>,RXY")]) ++ c<y>\t%0,%1 ++ c<g>rl\t%0,%1" ++ [(set_attr "op_type" "RR<E>,RI,SIL,RIL,RX<Y>,RXY,RIL") ++ (set_attr "cpu_facility" "*,*,z10,extimm,*,*,z10") ++ (set_attr "type" "*,*,*,*,*,*,larl") ++ (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,z10_super,z10_super")]) + + + ; Compare (unsigned) instructions + ++(define_insn "*cmpsi_ccu_zerohi_rlsi" ++ [(set (reg CC_REGNUM) ++ (compare (zero_extend:SI (mem:HI (match_operand:SI 1 ++ "larl_operand" "X"))) ++ (match_operand:SI 0 "register_operand" "d")))] ++ "s390_match_ccmode(insn, CCURmode) && TARGET_Z10" ++ "clhrl\t%0,%1" ++ [(set_attr "op_type" "RIL") ++ (set_attr "type" "larl")]) ++ ++; clhrl, clghrl ++(define_insn "*cmp<GPR:mode>_ccu_zerohi_rldi" ++ [(set (reg CC_REGNUM) ++ (compare (zero_extend:GPR (mem:HI (match_operand:DI 1 ++ "larl_operand" "X"))) ++ (match_operand:GPR 0 "register_operand" "d")))] ++ "s390_match_ccmode(insn, CCURmode) && TARGET_Z10" ++ "cl<g>hrl\t%0,%1" ++ [(set_attr "op_type" "RIL") ++ (set_attr "type" "larl") ++ (set_attr "z10prop" "z10_super")]) ++ + (define_insn "*cmpdi_ccu_zero" + [(set (reg CC_REGNUM) +- (compare (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m")) +- (match_operand:DI 0 "register_operand" "d,d")))] ++ (compare (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" ++ "d,RT,b")) ++ (match_operand:DI 0 "register_operand" "d, d,d")))] + "s390_match_ccmode (insn, CCURmode) && TARGET_64BIT" + "@ + clgfr\t%0,%1 +- clgf\t%0,%1" +- [(set_attr "op_type" "RRE,RXY")]) ++ clgf\t%0,%1 ++ clgfrl\t%0,%1" ++ [(set_attr "op_type" "RRE,RXY,RIL") ++ (set_attr "cpu_facility" "*,*,z10") ++ (set_attr "type" "*,*,larl") ++ (set_attr "z10prop" "z10_super_c,z10_super_E1,z10_super")]) + + (define_insn "*cmpdi_ccu" + [(set (reg CC_REGNUM) +- (compare (match_operand:DI 0 "nonimmediate_operand" "d,d,d,Q,BQ") +- (match_operand:DI 1 "general_operand" "d,Op,m,BQ,Q")))] ++ (compare (match_operand:DI 0 "nonimmediate_operand" ++ "d, d,d,Q, d, Q,BQ") ++ (match_operand:DI 1 "general_operand" ++ "d,Op,b,D,RT,BQ,Q")))] + "s390_match_ccmode (insn, CCUmode) && TARGET_64BIT" + "@ + clgr\t%0,%1 + clgfi\t%0,%1 ++ clgrl\t%0,%1 ++ clghsi\t%0,%x1 + clg\t%0,%1 + # + #" +- [(set_attr "op_type" "RRE,RIL,RXY,SS,SS")]) ++ [(set_attr "op_type" "RRE,RIL,RIL,SIL,RXY,SS,SS") ++ (set_attr "cpu_facility" "*,extimm,z10,z10,*,*,*") ++ (set_attr "type" "*,*,larl,*,*,*,*") ++ (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,*,*")]) + + (define_insn "*cmpsi_ccu" + [(set (reg CC_REGNUM) +- (compare (match_operand:SI 0 "nonimmediate_operand" "d,d,d,d,Q,BQ") +- (match_operand:SI 1 "general_operand" "d,Os,R,T,BQ,Q")))] ++ (compare (match_operand:SI 0 "nonimmediate_operand" "d, d,d,Q,d,d, Q,BQ") ++ (match_operand:SI 1 "general_operand" "d,Os,b,D,R,T,BQ, Q")))] + "s390_match_ccmode (insn, CCUmode)" + "@ + clr\t%0,%1 + clfi\t%0,%o1 ++ clrl\t%0,%1 ++ clfhsi\t%0,%x1 + cl\t%0,%1 + cly\t%0,%1 + # + #" +- [(set_attr "op_type" "RR,RIL,RX,RXY,SS,SS")]) ++ [(set_attr "op_type" "RR,RIL,RIL,SIL,RX,RXY,SS,SS") ++ (set_attr "cpu_facility" "*,extimm,z10,z10,*,*,*,*") ++ (set_attr "type" "*,*,larl,*,*,*,*,*") ++ (set_attr "z10prop" "z10_super_c,z10_super,z10_super,z10_super,z10_super,z10_super,*,*")]) + + (define_insn "*cmphi_ccu" + [(set (reg CC_REGNUM) +- (compare (match_operand:HI 0 "nonimmediate_operand" "d,d,Q,BQ") +- (match_operand:HI 1 "general_operand" "Q,S,BQ,Q")))] ++ (compare (match_operand:HI 0 "nonimmediate_operand" "d,d,Q,Q,BQ") ++ (match_operand:HI 1 "general_operand" "Q,S,D,BQ,Q")))] + "s390_match_ccmode (insn, CCUmode) + && !register_operand (operands[1], HImode)" + "@ + clm\t%0,3,%S1 + clmy\t%0,3,%S1 ++ clhhsi\t%0,%1 + # + #" +- [(set_attr "op_type" "RS,RSY,SS,SS")]) ++ [(set_attr "op_type" "RS,RSY,SIL,SS,SS") ++ (set_attr "cpu_facility" "*,*,z10,*,*") ++ (set_attr "z10prop" "*,*,z10_super,*,*")]) + + (define_insn "*cmpqi_ccu" + [(set (reg CC_REGNUM) +@@ -792,7 +950,8 @@ + cliy\t%S0,%b1 + # + #" +- [(set_attr "op_type" "RS,RSY,SI,SIY,SS,SS")]) ++ [(set_attr "op_type" "RS,RSY,SI,SIY,SS,SS") ++ (set_attr "z10prop" "*,*,z10_super,z10_super,*,*")]) + + + ; Block compare (CLC) instruction patterns. +@@ -839,7 +998,7 @@ + "s390_match_ccmode(insn, CCSmode) && TARGET_HARD_FLOAT" + "lt<xde><bt>r\t%0,%0" + [(set_attr "op_type" "RRE") +- (set_attr "type" "fsimp<bfp>")]) ++ (set_attr "type" "fsimp<mode>")]) + + ; cxtr, cxbr, cdbr, cebr, cxb, cdb, ceb, cxbtr, cdbtr + (define_insn "*cmp<mode>_ccs" +@@ -851,8 +1010,67 @@ + c<xde><bt>r\t%0,%1 + c<xde>b\t%0,%1" + [(set_attr "op_type" "RRE,RXE") +- (set_attr "type" "fsimp<bfp>")]) ++ (set_attr "type" "fsimp<mode>")]) + ++ ++; Compare and Branch instructions ++ ++; cij, cgij, crj, cgrj, cfi, cgfi, cr, cgr ++; The following instructions do a complementary access of their second ++; operand (z01 only): crj_c, cgrjc, cr, cgr ++(define_insn "*cmp_and_br_signed_<mode>" ++ [(set (pc) ++ (if_then_else (match_operator 0 "s390_signed_integer_comparison" ++ [(match_operand:GPR 1 "register_operand" "d,d") ++ (match_operand:GPR 2 "nonmemory_operand" "d,C")]) ++ (label_ref (match_operand 3 "" "")) ++ (pc))) ++ (clobber (reg:CC CC_REGNUM))] ++ "TARGET_Z10" ++{ ++ if (get_attr_length (insn) == 6) ++ return which_alternative ? ++ "c<g>ij%C0\t%1,%c2,%l3" : "c<g>rj%C0\t%1,%2,%l3"; ++ else ++ return which_alternative ? ++ "c<g>fi\t%1,%c2\;jg%C0\t%l3" : "c<g>r\t%1,%2\;jg%C0\t%l3"; ++} ++ [(set_attr "op_type" "RIE") ++ (set_attr "type" "branch") ++ (set_attr "z10prop" "z10_cobra,z10_super") ++ (set (attr "length") ++ (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000)) ++ (const_int 6) (const_int 12)))]) ; 8 byte for cr/jg ++ ; 10 byte for cgr/jg ++ ++; clij, clgij, clrj, clgrj, clfi, clgfi, clr, clgr ++; The following instructions do a complementary access of their second ++; operand (z10 only): clrj, clgrj, clr, clgr ++(define_insn "*cmp_and_br_unsigned_<mode>" ++ [(set (pc) ++ (if_then_else (match_operator 0 "s390_unsigned_integer_comparison" ++ [(match_operand:GPR 1 "register_operand" "d,d") ++ (match_operand:GPR 2 "nonmemory_operand" "d,I")]) ++ (label_ref (match_operand 3 "" "")) ++ (pc))) ++ (clobber (reg:CC CC_REGNUM))] ++ "TARGET_Z10" ++{ ++ if (get_attr_length (insn) == 6) ++ return which_alternative ? ++ "cl<g>ij%C0\t%1,%b2,%l3" : "cl<g>rj%C0\t%1,%2,%l3"; ++ else ++ return which_alternative ? ++ "cl<g>fi\t%1,%b2\;jg%C0\t%l3" : "cl<g>r\t%1,%2\;jg%C0\t%l3"; ++} ++ [(set_attr "op_type" "RIE") ++ (set_attr "type" "branch") ++ (set_attr "z10prop" "z10_cobra,z10_super") ++ (set (attr "length") ++ (if_then_else (lt (abs (minus (pc) (match_dup 3))) (const_int 60000)) ++ (const_int 6) (const_int 12)))]) ; 8 byte for clr/jg ++ ; 10 byte for clgr/jg ++ + ;; + ;;- Move instructions. + ;; +@@ -863,7 +1081,7 @@ + + (define_insn "movti" + [(set (match_operand:TI 0 "nonimmediate_operand" "=d,QS,d,o,Q") +- (match_operand:TI 1 "general_operand" "QS,d,dPm,d,Q"))] ++ (match_operand:TI 1 "general_operand" "QS,d,dPRT,d,Q"))] + "TARGET_64BIT" + "@ + lmg\t%0,%N0,%S1 +@@ -919,6 +1137,60 @@ + ; Patterns used for secondary reloads + ; + ++; z10 provides move instructions accepting larl memory operands. ++; Unfortunately there is no such variant for QI, TI and FP mode moves. ++; These patterns are also used for unaligned SI and DI accesses. ++ ++(define_expand "reload<INTALL:mode><P:mode>_tomem_z10" ++ [(parallel [(match_operand:INTALL 0 "memory_operand" "") ++ (match_operand:INTALL 1 "register_operand" "=d") ++ (match_operand:P 2 "register_operand" "=&a")])] ++ "TARGET_Z10" ++{ ++ s390_reload_symref_address (operands[1], operands[0], operands[2], 1); ++ DONE; ++}) ++ ++(define_expand "reload<INTALL:mode><P:mode>_toreg_z10" ++ [(parallel [(match_operand:INTALL 0 "register_operand" "=d") ++ (match_operand:INTALL 1 "memory_operand" "") ++ (match_operand:P 2 "register_operand" "=a")])] ++ "TARGET_Z10" ++{ ++ s390_reload_symref_address (operands[0], operands[1], operands[2], 0); ++ DONE; ++}) ++ ++(define_expand "reload<FPALL:mode><P:mode>_tomem_z10" ++ [(parallel [(match_operand:FPALL 0 "memory_operand" "") ++ (match_operand:FPALL 1 "register_operand" "=d") ++ (match_operand:P 2 "register_operand" "=&a")])] ++ "TARGET_Z10" ++{ ++ s390_reload_symref_address (operands[1], operands[0], operands[2], 1); ++ DONE; ++}) ++ ++(define_expand "reload<FPALL:mode><P:mode>_toreg_z10" ++ [(parallel [(match_operand:FPALL 0 "register_operand" "=d") ++ (match_operand:FPALL 1 "memory_operand" "") ++ (match_operand:P 2 "register_operand" "=a")])] ++ "TARGET_Z10" ++{ ++ s390_reload_symref_address (operands[0], operands[1], operands[2], 0); ++ DONE; ++}) ++ ++(define_expand "reload<P:mode>_larl_odd_addend_z10" ++ [(parallel [(match_operand:P 0 "register_operand" "=d") ++ (match_operand:P 1 "larl_operand" "") ++ (match_operand:P 2 "register_operand" "=a")])] ++ "TARGET_Z10" ++{ ++ s390_reload_larl_operand (operands[0], operands[1], operands[2]); ++ DONE; ++}) ++ + ; Handles loading a PLUS (load address) expression + + (define_expand "reload<mode>_plus" +@@ -984,16 +1256,17 @@ + && !FP_REG_P (operands[0])" + "larl\t%0,%1" + [(set_attr "op_type" "RIL") +- (set_attr "type" "larl")]) ++ (set_attr "type" "larl") ++ (set_attr "z10prop" "z10_super_A1")]) + +-(define_insn "*movdi_64dfp" ++(define_insn "*movdi_64" + [(set (match_operand:DI 0 "nonimmediate_operand" +- "=d,d,d,d,d,d,d,d,f,d,d,d,d, +- m,!*f,!*f,!*f,!R,!T,d,t,Q,t,?Q") ++ "=d,d,d,d,d,d,d,d,f,d,d,d,d,d, ++ RT,!*f,!*f,!*f,!R,!T,b,Q,d,t,Q,t,?Q") + (match_operand:DI 1 "general_operand" +- "K,N0HD0,N1HD0,N2HD0,N3HD0,Os,N0SD0,N1SD0,d,f,L,d,m, +- d,*f,R,T,*f,*f,t,d,t,Q,?Q"))] +- "TARGET_64BIT && TARGET_DFP" ++ "K,N0HD0,N1HD0,N2HD0,N3HD0,Os,N0SD0,N1SD0,d,f,L,b,d,RT, ++ d,*f,R,T,*f,*f,d,K,t,d,t,Q,?Q"))] ++ "TARGET_64BIT" + "@ + lghi\t%0,%h1 + llihh\t%0,%i1 +@@ -1006,6 +1279,7 @@ + ldgr\t%0,%1 + lgdr\t%0,%1 + lay\t%0,%a1 ++ lgrl\t%0,%1 + lgr\t%0,%1 + lg\t%0,%1 + stg\t%1,%0 +@@ -1014,81 +1288,50 @@ + ldy\t%0,%1 + std\t%1,%0 + stdy\t%1,%0 ++ stgrl\t%1,%0 ++ mvghi\t%0,%1 + # + # + stam\t%1,%N1,%S0 + lam\t%0,%N0,%S1 + #" +- [(set_attr "op_type" "RI,RI,RI,RI,RI,RIL,RIL,RIL,RRE,RRE,RXY,RRE,RXY,RXY, +- RR,RX,RXY,RX,RXY,*,*,RS,RS,SS") +- (set_attr "type" "*,*,*,*,*,*,*,*,floaddf,floaddf,la,lr,load,store, +- floaddf,floaddf,floaddf,fstoredf,fstoredf,*,*,*,*,*")]) ++ [(set_attr "op_type" "RI,RI,RI,RI,RI,RIL,RIL,RIL,RRE,RRE,RXY,RIL,RRE,RXY, ++ RXY,RR,RX,RXY,RX,RXY,RIL,SIL,*,*,RS,RS,SS") ++ (set_attr "type" "*,*,*,*,*,*,*,*,floaddf,floaddf,la,larl,lr,load,store, ++ floaddf,floaddf,floaddf,fstoredf,fstoredf,larl,*,*,*, ++ *,*,*") ++ (set_attr "cpu_facility" "*,*,*,*,*,extimm,extimm,extimm,dfp,dfp,longdisp, ++ z10,*,*,*,*,*,longdisp,*,longdisp, ++ z10,z10,*,*,*,*,*") ++ (set_attr "z10prop" "z10_fwd_A1, ++ z10_fwd_E1, ++ z10_fwd_E1, ++ z10_fwd_E1, ++ z10_fwd_E1, ++ z10_fwd_A1, ++ z10_fwd_E1, ++ z10_fwd_E1, ++ *, ++ *, ++ z10_fwd_A1, ++ z10_fwd_A3, ++ z10_fr_E1, ++ z10_fwd_A3, ++ z10_rec, ++ *, ++ *, ++ *, ++ *, ++ *, ++ z10_rec, ++ z10_super, ++ *, ++ *, ++ *, ++ *, ++ *") ++]) + +-(define_insn "*movdi_64extimm" +- [(set (match_operand:DI 0 "nonimmediate_operand" +- "=d,d,d,d,d,d,d,d,d,d,d,m,!*f,!*f,!*f,!R,!T,d,t,Q,t,?Q") +- (match_operand:DI 1 "general_operand" +- "K,N0HD0,N1HD0,N2HD0,N3HD0,Os,N0SD0,N1SD0,L,d,m,d,*f,R,T,*f,*f,t,d,t,Q,?Q"))] +- "TARGET_64BIT && TARGET_EXTIMM" +- "@ +- lghi\t%0,%h1 +- llihh\t%0,%i1 +- llihl\t%0,%i1 +- llilh\t%0,%i1 +- llill\t%0,%i1 +- lgfi\t%0,%1 +- llihf\t%0,%k1 +- llilf\t%0,%k1 +- lay\t%0,%a1 +- lgr\t%0,%1 +- lg\t%0,%1 +- stg\t%1,%0 +- ldr\t%0,%1 +- ld\t%0,%1 +- ldy\t%0,%1 +- std\t%1,%0 +- stdy\t%1,%0 +- # +- # +- stam\t%1,%N1,%S0 +- lam\t%0,%N0,%S1 +- #" +- [(set_attr "op_type" "RI,RI,RI,RI,RI,RIL,RIL,RIL,RXY,RRE,RXY,RXY, +- RR,RX,RXY,RX,RXY,*,*,RS,RS,SS") +- (set_attr "type" "*,*,*,*,*,*,*,*,la,lr,load,store, +- floaddf,floaddf,floaddf,fstoredf,fstoredf,*,*,*,*,*")]) +- +-(define_insn "*movdi_64" +- [(set (match_operand:DI 0 "nonimmediate_operand" +- "=d,d,d,d,d,d,d,d,m,!*f,!*f,!*f,!R,!T,d,t,Q,t,?Q") +- (match_operand:DI 1 "general_operand" +- "K,N0HD0,N1HD0,N2HD0,N3HD0,L,d,m,d,*f,R,T,*f,*f,t,d,t,Q,?Q"))] +- "TARGET_64BIT && !TARGET_EXTIMM" +- "@ +- lghi\t%0,%h1 +- llihh\t%0,%i1 +- llihl\t%0,%i1 +- llilh\t%0,%i1 +- llill\t%0,%i1 +- lay\t%0,%a1 +- lgr\t%0,%1 +- lg\t%0,%1 +- stg\t%1,%0 +- ldr\t%0,%1 +- ld\t%0,%1 +- ldy\t%0,%1 +- std\t%1,%0 +- stdy\t%1,%0 +- # +- # +- stam\t%1,%N1,%S0 +- lam\t%0,%N0,%S1 +- #" +- [(set_attr "op_type" "RI,RI,RI,RI,RI,RXY,RRE,RXY,RXY, +- RR,RX,RXY,RX,RXY,*,*,RS,RS,SS") +- (set_attr "type" "*,*,*,*,*,la,lr,load,store, +- floaddf,floaddf,floaddf,fstoredf,fstoredf,*,*,*,*,*")]) +- + (define_split + [(set (match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "register_operand" ""))] +@@ -1123,8 +1366,10 @@ + s390_split_access_reg (operands[0], &operands[3], &operands[4]);") + + (define_insn "*movdi_31" +- [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,Q,S,d,o,!*f,!*f,!*f,!R,!T,Q") +- (match_operand:DI 1 "general_operand" "Q,S,d,d,dPm,d,*f,R,T,*f,*f,Q"))] ++ [(set (match_operand:DI 0 "nonimmediate_operand" ++ "=d,d,Q,S,d ,o,!*f,!*f,!*f,!R,!T,Q,d") ++ (match_operand:DI 1 "general_operand" ++ " Q,S,d,d,dPRT,d, *f, R, T,*f,*f,Q,b"))] + "!TARGET_64BIT" + "@ + lm\t%0,%N0,%S1 +@@ -1138,11 +1383,28 @@ + ldy\t%0,%1 + std\t%1,%0 + stdy\t%1,%0 ++ # + #" +- [(set_attr "op_type" "RS,RSY,RS,RSY,*,*,RR,RX,RXY,RX,RXY,SS") +- (set_attr "type" "lm,lm,stm,stm,*,*,floaddf,floaddf,floaddf,fstoredf,fstoredf,*")]) ++ [(set_attr "op_type" "RS,RSY,RS,RSY,*,*,RR,RX,RXY,RX,RXY,SS,*") ++ (set_attr "type" "lm,lm,stm,stm,*,*,floaddf,floaddf,floaddf,fstoredf,fstoredf,*,*") ++ (set_attr "cpu_facility" "*,*,*,*,*,*,*,*,*,*,*,*,z10")]) + ++; For a load from a symbol ref we can use one of the target registers ++; together with larl to load the address. + (define_split ++ [(set (match_operand:DI 0 "register_operand" "") ++ (match_operand:DI 1 "memory_operand" ""))] ++ "!TARGET_64BIT && reload_completed && TARGET_Z10 ++ && larl_operand (XEXP (operands[1], 0), SImode)" ++ [(set (match_dup 2) (match_dup 3)) ++ (set (match_dup 0) (match_dup 1))] ++{ ++ operands[2] = operand_subword (operands[0], 1, 0, DImode); ++ operands[3] = XEXP (operands[1], 0); ++ operands[1] = replace_equiv_address (operands[1], operands[2]); ++}) ++ ++(define_split + [(set (match_operand:DI 0 "nonimmediate_operand" "") + (match_operand:DI 1 "general_operand" ""))] + "!TARGET_64BIT && reload_completed +@@ -1203,7 +1465,8 @@ + la\t%0,%a1 + lay\t%0,%a1" + [(set_attr "op_type" "RX,RXY") +- (set_attr "type" "la")]) ++ (set_attr "type" "la") ++ (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")]) + + (define_peephole2 + [(parallel +@@ -1254,13 +1517,14 @@ + && !FP_REG_P (operands[0])" + "larl\t%0,%1" + [(set_attr "op_type" "RIL") +- (set_attr "type" "larl")]) ++ (set_attr "type" "larl") ++ (set_attr "z10prop" "z10_super_A1")]) + + (define_insn "*movsi_zarch" + [(set (match_operand:SI 0 "nonimmediate_operand" +- "=d,d,d,d,d,d,d,d,R,T,!*f,!*f,!*f,!R,!T,d,t,Q,t,?Q") ++ "=d,d,d,d,d,d,d,d,d,R,T,!*f,!*f,!*f,!R,!T,d,t,Q,b,Q,t,?Q") + (match_operand:SI 1 "general_operand" +- "K,N0HS0,N1HS0,Os,L,d,R,T,d,d,*f,R,T,*f,*f,t,d,t,Q,?Q"))] ++ "K,N0HS0,N1HS0,Os,L,b,d,R,T,d,d,*f,R,T,*f,*f,t,d,t,d,K,Q,?Q"))] + "TARGET_ZARCH" + "@ + lhi\t%0,%h1 +@@ -1268,6 +1532,7 @@ + llill\t%0,%i1 + iilf\t%0,%o1 + lay\t%0,%a1 ++ lrl\t%0,%1 + lr\t%0,%1 + l\t%0,%1 + ly\t%0,%1 +@@ -1281,12 +1546,60 @@ + ear\t%0,%1 + sar\t%0,%1 + stam\t%1,%1,%S0 ++ strl\t%1,%0 ++ mvhi\t%0,%1 + lam\t%0,%0,%S1 + #" +- [(set_attr "op_type" "RI,RI,RI,RIL,RXY,RR,RX,RXY,RX,RXY, +- RR,RX,RXY,RX,RXY,RRE,RRE,RS,RS,SS") +- (set_attr "type" "*,*,*,*,la,lr,load,load,store,store, +- floadsf,floadsf,floadsf,fstoresf,fstoresf,*,*,*,*,*")]) ++ [(set_attr "op_type" "RI,RI,RI,RIL,RXY,RIL,RR,RX,RXY,RX,RXY, ++ RR,RX,RXY,RX,RXY,RRE,RRE,RS,RIL,SIL,RS,SS") ++ (set_attr "type" "*, ++ *, ++ *, ++ *, ++ la, ++ larl, ++ lr, ++ load, ++ load, ++ store, ++ store, ++ floadsf, ++ floadsf, ++ floadsf, ++ fstoresf, ++ fstoresf, ++ *, ++ *, ++ *, ++ larl, ++ *, ++ *, ++ *") ++ (set_attr "cpu_facility" "*,*,*,extimm,longdisp,z10,*,*,longdisp,*,longdisp, ++ *,*,longdisp,*,longdisp,*,*,*,z10,z10,*,*") ++ (set_attr "z10prop" "z10_fwd_A1, ++ z10_fwd_E1, ++ z10_fwd_E1, ++ z10_fwd_A1, ++ z10_fwd_A1, ++ z10_fwd_A3, ++ z10_fr_E1, ++ z10_fwd_A3, ++ z10_fwd_A3, ++ z10_super, ++ z10_rec, ++ *, ++ *, ++ *, ++ *, ++ *, ++ z10_super_E1, ++ z10_super, ++ *, ++ z10_rec, ++ z10_super, ++ *, ++ *")]) + + (define_insn "*movsi_esa" + [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,R,!*f,!*f,!R,d,t,Q,t,?Q") +@@ -1306,7 +1619,20 @@ + lam\t%0,%0,%S1 + #" + [(set_attr "op_type" "RI,RR,RX,RX,RR,RX,RX,RRE,RRE,RS,RS,SS") +- (set_attr "type" "*,lr,load,store,floadsf,floadsf,fstoresf,*,*,*,*,*")]) ++ (set_attr "type" "*,lr,load,store,floadsf,floadsf,fstoresf,*,*,*,*,*") ++ (set_attr "z10prop" "z10_fwd_A1, ++ z10_fr_E1, ++ z10_fwd_A3, ++ z10_super, ++ *, ++ *, ++ *, ++ z10_super_E1, ++ z10_super, ++ *, ++ *, ++ *") ++]) + + (define_peephole2 + [(set (match_operand:SI 0 "register_operand" "") +@@ -1327,7 +1653,8 @@ + la\t%0,%a1 + lay\t%0,%a1" + [(set_attr "op_type" "RX,RXY") +- (set_attr "type" "la")]) ++ (set_attr "type" "la") ++ (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")]) + + (define_peephole2 + [(parallel +@@ -1362,7 +1689,8 @@ + la\t%0,%a1 + lay\t%0,%a1" + [(set_attr "op_type" "RX,RXY") +- (set_attr "type" "la")]) ++ (set_attr "type" "la") ++ (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")]) + + (define_insn_and_split "*la_31_and_cc" + [(set (match_operand:SI 0 "register_operand" "=d") +@@ -1387,7 +1715,8 @@ + la\t%0,%a1 + lay\t%0,%a1" + [(set_attr "op_type" "RX") +- (set_attr "type" "la")]) ++ (set_attr "type" "la") ++ (set_attr "z10prop" "z10_fwd_A1,z10_fwd_A1")]) + + ; + ; movhi instruction pattern(s). +@@ -1412,19 +1741,33 @@ + }) + + (define_insn "*movhi" +- [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,R,T,?Q") +- (match_operand:HI 1 "general_operand" "d,n,R,T,d,d,?Q"))] ++ [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,d,d,d,R,T,b,Q,?Q") ++ (match_operand:HI 1 "general_operand" " d,n,R,T,b,d,d,d,K,?Q"))] + "" + "@ + lr\t%0,%1 + lhi\t%0,%h1 + lh\t%0,%1 + lhy\t%0,%1 ++ lhrl\t%0,%1 + sth\t%1,%0 + sthy\t%1,%0 ++ sthrl\t%1,%0 ++ mvhhi\t%0,%1 + #" +- [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SS") +- (set_attr "type" "lr,*,*,*,store,store,*")]) ++ [(set_attr "op_type" "RR,RI,RX,RXY,RIL,RX,RXY,RIL,SIL,SS") ++ (set_attr "type" "lr,*,*,*,larl,store,store,store,*,*") ++ (set_attr "cpu_facility" "*,*,*,*,z10,*,*,z10,z10,*") ++ (set_attr "z10prop" "z10_fr_E1, ++ z10_fwd_A1, ++ z10_super_E1, ++ z10_super_E1, ++ z10_super_E1, ++ z10_super, ++ z10_rec, ++ z10_rec, ++ z10_super, ++ *")]) + + (define_peephole2 + [(set (match_operand:HI 0 "register_operand" "") +@@ -1473,7 +1816,16 @@ + mviy\t%S0,%b1 + #" + [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SI,SIY,SS") +- (set_attr "type" "lr,*,*,*,store,store,store,store,*")]) ++ (set_attr "type" "lr,*,*,*,store,store,store,store,*") ++ (set_attr "z10prop" "z10_fr_E1, ++ z10_fwd_A1, ++ z10_super_E1, ++ z10_super_E1, ++ z10_super, ++ z10_rec, ++ z10_super, ++ z10_super, ++ *")]) + + (define_peephole2 + [(set (match_operand:QI 0 "nonimmediate_operand" "") +@@ -1496,7 +1848,8 @@ + "@ + ic\t%0,%1 + icy\t%0,%1" +- [(set_attr "op_type" "RX,RXY")]) ++ [(set_attr "op_type" "RX,RXY") ++ (set_attr "z10prop" "z10_super_E1,z10_super")]) + + ; + ; movstricthi instruction pattern(s). +@@ -1510,7 +1863,8 @@ + "@ + icm\t%0,3,%S1 + icmy\t%0,3,%S1" +- [(set_attr "op_type" "RS,RSY")]) ++ [(set_attr "op_type" "RS,RSY") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1")]) + + ; + ; movstrictsi instruction pattern(s). +@@ -1526,7 +1880,8 @@ + ly\t%0,%1 + ear\t%0,%1" + [(set_attr "op_type" "RR,RX,RXY,RRE") +- (set_attr "type" "lr,load,load,*")]) ++ (set_attr "type" "lr,load,load,*") ++ (set_attr "z10prop" "z10_fr_E1,z10_fwd_A3,z10_fwd_A3,z10_super_E1")]) + + ; + ; mov(tf|td) instruction pattern(s). +@@ -1540,7 +1895,7 @@ + + (define_insn "*mov<mode>_64" + [(set (match_operand:TD_TF 0 "nonimmediate_operand" "=f,f,f,o, d,QS, d,o,Q") +- (match_operand:TD_TF 1 "general_operand" " G,f,o,f,QS, d,dm,d,Q"))] ++ (match_operand:TD_TF 1 "general_operand" " G,f,o,f,QS, d,dRT,d,Q"))] + "TARGET_64BIT" + "@ + lzxr\t%0 +@@ -1616,7 +1971,7 @@ + (define_split + [(set (match_operand:TD_TF 0 "register_operand" "") + (match_operand:TD_TF 1 "memory_operand" ""))] +- "reload_completed && offsettable_memref_p (operands[1]) ++ "reload_completed && offsettable_memref_p (operands[1]) + && FP_REG_P (operands[0])" + [(set (match_dup 2) (match_dup 4)) + (set (match_dup 3) (match_dup 5))] +@@ -1657,9 +2012,9 @@ + + (define_insn "*mov<mode>_64dfp" + [(set (match_operand:DD_DF 0 "nonimmediate_operand" +- "=f,f,f,d,f,f,R,T,d,d,m,?Q") ++ "=f,f,f,d,f,f,R,T,d,d,RT,?Q") + (match_operand:DD_DF 1 "general_operand" +- "G,f,d,f,R,T,f,f,d,m,d,?Q"))] ++ "G,f,d,f,R,T,f,f,d,RT,d,?Q"))] + "TARGET_64BIT && TARGET_DFP" + "@ + lzdr\t%0 +@@ -1676,11 +2031,24 @@ + #" + [(set_attr "op_type" "RRE,RR,RRE,RRE,RX,RXY,RX,RXY,RRE,RXY,RXY,SS") + (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,floaddf,floaddf, +- fstoredf,fstoredf,lr,load,store,*")]) ++ fstoredf,fstoredf,lr,load,store,*") ++ (set_attr "z10prop" "*, ++ *, ++ *, ++ *, ++ *, ++ *, ++ *, ++ *, ++ z10_fr_E1, ++ z10_fwd_A3, ++ z10_rec, ++ *") ++]) + + (define_insn "*mov<mode>_64" +- [(set (match_operand:DD_DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,m,?Q") +- (match_operand:DD_DF 1 "general_operand" "G,f,R,T,f,f,d,m,d,?Q"))] ++ [(set (match_operand:DD_DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d, d,RT,?Q") ++ (match_operand:DD_DF 1 "general_operand" "G,f,R,T,f,f,d,RT, d,?Q"))] + "TARGET_64BIT" + "@ + lzdr\t%0 +@@ -1694,14 +2062,24 @@ + stg\t%1,%0 + #" + [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RRE,RXY,RXY,SS") +- (set_attr "type" "fsimp<bfp>,fload<bfp>,fload<bfp>,fload<bfp>, +- fstore<bfp>,fstore<bfp>,lr,load,store,*")]) ++ (set_attr "type" "fsimp<mode>,fload<mode>,fload<mode>,fload<mode>, ++ fstore<mode>,fstore<mode>,lr,load,store,*") ++ (set_attr "z10prop" "*, ++ *, ++ *, ++ *, ++ *, ++ *, ++ z10_fr_E1, ++ z10_fwd_A3, ++ z10_rec, ++ *")]) + + (define_insn "*mov<mode>_31" + [(set (match_operand:DD_DF 0 "nonimmediate_operand" +- "=f,f,f,f,R,T,d,d,Q,S, d,o,Q") ++ "=f,f,f,f,R,T,d,d,Q,S, d,o,Q") + (match_operand:DD_DF 1 "general_operand" +- " G,f,R,T,f,f,Q,S,d,d,dPm,d,Q"))] ++ " G,f,R,T,f,f,Q,S,d,d,dPRT,d,Q"))] + "!TARGET_64BIT" + "@ + lzdr\t%0 +@@ -1718,8 +2096,8 @@ + # + #" + [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RS,RSY,RS,RSY,*,*,SS") +- (set_attr "type" "fsimp<bfp>,fload<bfp>,fload<bfp>,fload<bfp>, +- fstore<bfp>,fstore<bfp>,lm,lm,stm,stm,*,*,*")]) ++ (set_attr "type" "fsimp<mode>,fload<mode>,fload<mode>,fload<mode>, ++ fstore<mode>,fstore<mode>,lm,lm,stm,stm,*,*,*")]) + + (define_split + [(set (match_operand:DD_DF 0 "nonimmediate_operand" "") +@@ -1786,8 +2164,20 @@ + sty\t%1,%0 + #" + [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RR,RX,RXY,RX,RXY,SS") +- (set_attr "type" "fsimp<bfp>,fload<bfp>,fload<bfp>,fload<bfp>, +- fstore<bfp>,fstore<bfp>,lr,load,load,store,store,*")]) ++ (set_attr "type" "fsimp<mode>,fload<mode>,fload<mode>,fload<mode>, ++ fstore<mode>,fstore<mode>,lr,load,load,store,store,*") ++ (set_attr "z10prop" "*, ++ *, ++ *, ++ *, ++ *, ++ *, ++ z10_fr_E1, ++ z10_fwd_A3, ++ z10_fwd_A3, ++ z10_super, ++ z10_rec, ++ *")]) + + ; + ; movcc instruction pattern +@@ -1806,7 +2196,8 @@ + l\t%1,%0 + ly\t%1,%0" + [(set_attr "op_type" "RR,RI,RRE,RX,RXY,RX,RXY") +- (set_attr "type" "lr,*,*,store,store,load,load")]) ++ (set_attr "type" "lr,*,*,store,store,load,load") ++ (set_attr "z10prop" "z10_fr_E1,*,*,z10_super,z10_rec,z10_fwd_A3,z10_fwd_A3")]) + + ; + ; Block move (MVC) patterns. +@@ -1846,7 +2237,7 @@ + (use (match_operand 5 "const_int_operand" ""))])] + "s390_offset_p (operands[0], operands[3], operands[2]) + && s390_offset_p (operands[1], operands[4], operands[2]) +- && !s390_overlap_p (operands[0], operands[1], ++ && !s390_overlap_p (operands[0], operands[1], + INTVAL (operands[2]) + INTVAL (operands[5])) + && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256" + [(parallel +@@ -2045,6 +2436,17 @@ + ;; String instructions. + ;; + ++(define_insn "*execute_rl" ++ [(match_parallel 0 "" ++ [(unspec [(match_operand 1 "register_operand" "a") ++ (match_operand 2 "" "") ++ (match_operand:SI 3 "larl_operand" "X")] UNSPEC_EXECUTE)])] ++ "TARGET_Z10 && GET_MODE_CLASS (GET_MODE (operands[1])) == MODE_INT ++ && GET_MODE_SIZE (GET_MODE (operands[1])) <= UNITS_PER_WORD" ++ "exrl\t%1,%3" ++ [(set_attr "op_type" "RIL") ++ (set_attr "type" "cs")]) ++ + (define_insn "*execute" + [(match_parallel 0 "" + [(unspec [(match_operand 1 "register_operand" "a") +@@ -2141,19 +2543,19 @@ + "clst\t%0,%1\;jo\t.-4" + [(set_attr "length" "8") + (set_attr "type" "vs")]) +- ++ + ; + ; movstr instruction pattern. + ; + + (define_expand "movstr" + [(set (reg:SI 0) (const_int 0)) +- (parallel ++ (parallel + [(clobber (match_dup 3)) + (set (match_operand:BLK 1 "memory_operand" "") + (match_operand:BLK 2 "memory_operand" "")) + (set (match_operand 0 "register_operand" "") +- (unspec [(match_dup 1) ++ (unspec [(match_dup 1) + (match_dup 2) + (reg:SI 0)] UNSPEC_MVST)) + (clobber (reg:CC CC_REGNUM))])] +@@ -2174,7 +2576,7 @@ + (set (mem:BLK (match_operand:P 1 "register_operand" "0")) + (mem:BLK (match_operand:P 3 "register_operand" "2"))) + (set (match_operand:P 0 "register_operand" "=d") +- (unspec [(mem:BLK (match_dup 1)) ++ (unspec [(mem:BLK (match_dup 1)) + (mem:BLK (match_dup 3)) + (reg:SI 0)] UNSPEC_MVST)) + (clobber (reg:CC CC_REGNUM))] +@@ -2182,16 +2584,16 @@ + "mvst\t%1,%2\;jo\t.-4" + [(set_attr "length" "8") + (set_attr "type" "vs")]) +- + ++ + ; + ; movmemM instruction pattern(s). + ; + + (define_expand "movmem<mode>" +- [(set (match_operand:BLK 0 "memory_operand" "") +- (match_operand:BLK 1 "memory_operand" "")) +- (use (match_operand:GPR 2 "general_operand" "")) ++ [(set (match_operand:BLK 0 "memory_operand" "") ; destination ++ (match_operand:BLK 1 "memory_operand" "")) ; source ++ (use (match_operand:GPR 2 "general_operand" "")) ; count + (match_operand 3 "" "")] + "" + "s390_expand_movmem (operands[0], operands[1], operands[2]); DONE;") +@@ -2210,15 +2612,16 @@ + "operands[3] = gen_rtx_SCRATCH (Pmode);") + + (define_insn "*movmem_short" +- [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q") +- (match_operand:BLK 1 "memory_operand" "Q,Q,Q")) +- (use (match_operand 2 "nonmemory_operand" "n,a,a")) +- (use (match_operand 3 "immediate_operand" "X,R,X")) +- (clobber (match_scratch 4 "=X,X,&a"))] ++ [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q") ++ (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q")) ++ (use (match_operand 2 "nonmemory_operand" "n,a,a,a")) ++ (use (match_operand 3 "immediate_operand" "X,R,X,X")) ++ (clobber (match_scratch 4 "=X,X,X,&a"))] + "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode) + && GET_MODE (operands[4]) == Pmode" + "#" +- [(set_attr "type" "cs")]) ++ [(set_attr "type" "cs") ++ (set_attr "cpu_facility" "*,*,z10,*")]) + + (define_split + [(set (match_operand:BLK 0 "memory_operand" "") +@@ -2251,11 +2654,25 @@ + (match_operand:BLK 1 "memory_operand" "")) + (use (match_operand 2 "register_operand" "")) + (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN))) ++ (clobber (scratch))] ++ "TARGET_Z10 && reload_completed" ++ [(parallel ++ [(unspec [(match_dup 2) (const_int 0) ++ (label_ref (match_dup 3))] UNSPEC_EXECUTE) ++ (set (match_dup 0) (match_dup 1)) ++ (use (const_int 1))])] ++ "operands[3] = gen_label_rtx ();") ++ ++(define_split ++ [(set (match_operand:BLK 0 "memory_operand" "") ++ (match_operand:BLK 1 "memory_operand" "")) ++ (use (match_operand 2 "register_operand" "")) ++ (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN))) + (clobber (match_operand 3 "register_operand" ""))] + "reload_completed && TARGET_CPU_ZARCH" + [(set (match_dup 3) (label_ref (match_dup 4))) + (parallel +- [(unspec [(match_dup 2) (mem:BLK (match_dup 3)) ++ [(unspec [(match_dup 2) (mem:BLK (match_dup 3)) + (label_ref (match_dup 4))] UNSPEC_EXECUTE) + (set (match_dup 0) (match_dup 1)) + (use (const_int 1))])] +@@ -2316,8 +2733,8 @@ + + (define_expand "signbit<mode>2" + [(set (reg:CCZ CC_REGNUM) +- (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f") +- (match_dup 2)] ++ (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f") ++ (match_dup 2)] + UNSPEC_TDC_INSN)) + (set (match_operand:SI 0 "register_operand" "=d") + (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CCZ_TO_INT))] +@@ -2328,8 +2745,8 @@ + + (define_expand "isinf<mode>2" + [(set (reg:CCZ CC_REGNUM) +- (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f") +- (match_dup 2)] ++ (unspec:CCZ [(match_operand:FP_ALL 1 "register_operand" "f") ++ (match_dup 2)] + UNSPEC_TDC_INSN)) + (set (match_operand:SI 0 "register_operand" "=d") + (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CCZ_TO_INT))] +@@ -2341,16 +2758,16 @@ + ; This insn is used to generate all variants of the Test Data Class + ; instruction, namely tcxb, tcdb, and tceb. The insn's first operand + ; is the register to be tested and the second one is the bit mask +-; specifying the required test(s). ++; specifying the required test(s). + ; + (define_insn "*TDC_insn_<mode>" + [(set (reg:CCZ CC_REGNUM) +- (unspec:CCZ [(match_operand:FP_ALL 0 "register_operand" "f") ++ (unspec:CCZ [(match_operand:FP_ALL 0 "register_operand" "f") + (match_operand:SI 1 "const_int_operand")] UNSPEC_TDC_INSN))] + "TARGET_HARD_FLOAT" + "t<_d>c<xde><bt>\t%0,%1" + [(set_attr "op_type" "RXE") +- (set_attr "type" "fsimp<bfp>")]) ++ (set_attr "type" "fsimp<mode>")]) + + (define_insn_and_split "*ccz_to_int" + [(set (match_operand:SI 0 "register_operand" "=d") +@@ -2389,16 +2806,17 @@ + "operands[2] = gen_rtx_SCRATCH (Pmode);") + + (define_insn "*clrmem_short" +- [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q") ++ [(set (match_operand:BLK 0 "memory_operand" "=Q,Q,Q,Q") + (const_int 0)) +- (use (match_operand 1 "nonmemory_operand" "n,a,a")) +- (use (match_operand 2 "immediate_operand" "X,R,X")) +- (clobber (match_scratch 3 "=X,X,&a")) ++ (use (match_operand 1 "nonmemory_operand" "n,a,a,a")) ++ (use (match_operand 2 "immediate_operand" "X,R,X,X")) ++ (clobber (match_scratch 3 "=X,X,X,&a")) + (clobber (reg:CC CC_REGNUM))] + "(GET_MODE (operands[1]) == Pmode || GET_MODE (operands[1]) == VOIDmode) + && GET_MODE (operands[3]) == Pmode" + "#" +- [(set_attr "type" "cs")]) ++ [(set_attr "type" "cs") ++ (set_attr "cpu_facility" "*,*,z10,*")]) + + (define_split + [(set (match_operand:BLK 0 "memory_operand" "") +@@ -2435,19 +2853,35 @@ + (const_int 0)) + (use (match_operand 1 "register_operand" "")) + (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN))) ++ (clobber (scratch)) ++ (clobber (reg:CC CC_REGNUM))] ++ "TARGET_Z10 && reload_completed" ++ [(parallel ++ [(unspec [(match_dup 1) (const_int 0) ++ (label_ref (match_dup 3))] UNSPEC_EXECUTE) ++ (set (match_dup 0) (const_int 0)) ++ (use (const_int 1)) ++ (clobber (reg:CC CC_REGNUM))])] ++ "operands[3] = gen_label_rtx ();") ++ ++(define_split ++ [(set (match_operand:BLK 0 "memory_operand" "") ++ (const_int 0)) ++ (use (match_operand 1 "register_operand" "")) ++ (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN))) + (clobber (match_operand 2 "register_operand" "")) + (clobber (reg:CC CC_REGNUM))] + "reload_completed && TARGET_CPU_ZARCH" + [(set (match_dup 2) (label_ref (match_dup 3))) + (parallel +- [(unspec [(match_dup 1) (mem:BLK (match_dup 2)) ++ [(unspec [(match_dup 1) (mem:BLK (match_dup 2)) + (label_ref (match_dup 3))] UNSPEC_EXECUTE) + (set (match_dup 0) (const_int 0)) + (use (const_int 1)) + (clobber (reg:CC CC_REGNUM))])] + "operands[3] = gen_label_rtx ();") + +-; Initialize a block of arbitrary length with (operands[2] % 256). ++; Initialize a block of arbitrary length with (operands[2] % 256). + + (define_expand "setmem_long" + [(parallel +@@ -2530,15 +2964,16 @@ + + (define_insn "*cmpmem_short" + [(set (reg:CCU CC_REGNUM) +- (compare:CCU (match_operand:BLK 0 "memory_operand" "Q,Q,Q") +- (match_operand:BLK 1 "memory_operand" "Q,Q,Q"))) +- (use (match_operand 2 "nonmemory_operand" "n,a,a")) +- (use (match_operand 3 "immediate_operand" "X,R,X")) +- (clobber (match_scratch 4 "=X,X,&a"))] ++ (compare:CCU (match_operand:BLK 0 "memory_operand" "Q,Q,Q,Q") ++ (match_operand:BLK 1 "memory_operand" "Q,Q,Q,Q"))) ++ (use (match_operand 2 "nonmemory_operand" "n,a,a,a")) ++ (use (match_operand 3 "immediate_operand" "X,R,X,X")) ++ (clobber (match_scratch 4 "=X,X,X,&a"))] + "(GET_MODE (operands[2]) == Pmode || GET_MODE (operands[2]) == VOIDmode) + && GET_MODE (operands[4]) == Pmode" + "#" +- [(set_attr "type" "cs")]) ++ [(set_attr "type" "cs") ++ (set_attr "cpu_facility" "*,*,z10,*")]) + + (define_split + [(set (reg:CCU CC_REGNUM) +@@ -2574,11 +3009,26 @@ + (match_operand:BLK 1 "memory_operand" ""))) + (use (match_operand 2 "register_operand" "")) + (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN))) ++ (clobber (scratch))] ++ "TARGET_Z10 && reload_completed" ++ [(parallel ++ [(unspec [(match_dup 2) (const_int 0) ++ (label_ref (match_dup 4))] UNSPEC_EXECUTE) ++ (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1))) ++ (use (const_int 1))])] ++ "operands[4] = gen_label_rtx ();") ++ ++(define_split ++ [(set (reg:CCU CC_REGNUM) ++ (compare:CCU (match_operand:BLK 0 "memory_operand" "") ++ (match_operand:BLK 1 "memory_operand" ""))) ++ (use (match_operand 2 "register_operand" "")) ++ (use (const:BLK (unspec:BLK [(const_int 0)] UNSPEC_INSN))) + (clobber (match_operand 3 "register_operand" ""))] + "reload_completed && TARGET_CPU_ZARCH" + [(set (match_dup 3) (label_ref (match_dup 4))) + (parallel +- [(unspec [(match_dup 2) (mem:BLK (match_dup 3)) ++ [(unspec [(match_dup 2) (mem:BLK (match_dup 3)) + (label_ref (match_dup 4))] UNSPEC_EXECUTE) + (set (reg:CCU CC_REGNUM) (compare:CCU (match_dup 0) (match_dup 1))) + (use (const_int 1))])] +@@ -2683,7 +3133,7 @@ + + (define_insn_and_split "*cmpint_sign_cc" + [(set (reg CC_REGNUM) +- (compare (ashiftrt:DI (ashift:DI (subreg:DI ++ (compare (ashiftrt:DI (ashift:DI (subreg:DI + (unspec:SI [(match_operand:CCU 1 "register_operand" "0")] + UNSPEC_CCU_TO_INT) 0) + (const_int 32)) (const_int 32)) +@@ -2717,7 +3167,8 @@ + "@ + icm\t%0,%2,%S1 + icmy\t%0,%2,%S1" +- [(set_attr "op_type" "RS,RSY")]) ++ [(set_attr "op_type" "RS,RSY") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1")]) + + (define_insn "*sethighpartdi_64" + [(set (match_operand:DI 0 "register_operand" "=d") +@@ -2737,8 +3188,10 @@ + "@ + icm\t%0,%2,%S1 + icmy\t%0,%2,%S1" +- [(set_attr "op_type" "RS,RSY")]) ++ [(set_attr "op_type" "RS,RSY") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1")]) + ++ + (define_insn_and_split "*extzv<mode>" + [(set (match_operand:GPR 0 "register_operand" "=d") + (zero_extract:GPR (match_operand:QI 1 "s_operand" "QS") +@@ -2807,6 +3260,85 @@ + FAIL; + }) + ++(define_insn "*insv<mode>_z10" ++ [(set (zero_extract:GPR (match_operand:GPR 0 "nonimmediate_operand" "+d") ++ (match_operand 1 "const_int_operand" "I") ++ (match_operand 2 "const_int_operand" "I")) ++ (match_operand:GPR 3 "nonimmediate_operand" "d")) ++ (clobber (reg:CC CC_REGNUM))] ++ "TARGET_Z10 ++ && (INTVAL (operands[1]) + INTVAL (operands[2])) <= ++ GET_MODE_BITSIZE (<MODE>mode)" ++{ ++ int start = INTVAL (operands[2]); ++ int size = INTVAL (operands[1]); ++ int offset = 64 - GET_MODE_BITSIZE (<MODE>mode); ++ ++ operands[2] = GEN_INT (offset + start); /* start bit position */ ++ operands[1] = GEN_INT (offset + start + size - 1); /* end bit position */ ++ operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - ++ start - size); /* left shift count */ ++ ++ return "risbg\t%0,%3,%b2,%b1,%b4"; ++} ++ [(set_attr "op_type" "RIE") ++ (set_attr "z10prop" "z10_super_E1")]) ++ ++; and op1 with a mask being 1 for the selected bits and 0 for the rest ++; and op3=op0 with a mask being 0 for the selected bits and 1 for the rest ++(define_insn "*insv<mode>_z10_noshift" ++ [(set (match_operand:GPR 0 "nonimmediate_operand" "=d") ++ (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d") ++ (match_operand 2 "const_int_operand" "n")) ++ (and:GPR (match_operand:GPR 3 "nonimmediate_operand" "0") ++ (match_operand 4 "const_int_operand" "n")))) ++ (clobber (reg:CC CC_REGNUM))] ++ "TARGET_Z10 ++ && s390_contiguous_bitmask_p (INTVAL (operands[2]), ++ GET_MODE_BITSIZE (<MODE>mode), NULL, NULL) ++ && INTVAL (operands[2]) == ~(INTVAL (operands[4]))" ++ ++{ ++ int start; ++ int size; ++ ++ s390_contiguous_bitmask_p (INTVAL (operands[2]), ++ GET_MODE_BITSIZE (<MODE>mode), &start, &size); ++ ++ operands[5] = GEN_INT (64 - start - size); /* start bit position */ ++ operands[6] = GEN_INT (64 - 1 - start); /* end bit position */ ++ operands[7] = const0_rtx; /* left shift count */ ++ ++ return "risbg\t%0,%1,%b5,%b6,%b7"; ++} ++ [(set_attr "op_type" "RIE") ++ (set_attr "z10prop" "z10_super_E1")]) ++ ++; and op1 with a mask being 1 for the selected bits and 0 for the rest ++(define_insn "*insv<mode>_or_z10_noshift" ++ [(set (match_operand:GPR 0 "nonimmediate_operand" "=d") ++ (ior:GPR (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "d") ++ (match_operand 2 "const_int_operand" "n")) ++ (match_operand:GPR 3 "nonimmediate_operand" "0"))) ++ (clobber (reg:CC CC_REGNUM))] ++ "TARGET_Z10 ++ && s390_contiguous_bitmask_p (INTVAL (operands[2]), ++ GET_MODE_BITSIZE (<MODE>mode), NULL, NULL)" ++{ ++ int start; ++ int size; ++ ++ s390_contiguous_bitmask_p (INTVAL (operands[2]), ++ GET_MODE_BITSIZE (<MODE>mode), &start, &size); ++ ++ operands[4] = GEN_INT (64 - start - size); /* start bit position */ ++ operands[5] = GEN_INT (64 - 1 - start); /* end bit position */ ++ operands[6] = const0_rtx; /* left shift count */ ++ ++ return "rosbg\t%0,%1,%b4,%b5,%b6"; ++} ++ [(set_attr "op_type" "RIE")]) ++ + (define_insn "*insv<mode>_mem_reg" + [(set (zero_extract:P (match_operand:QI 0 "memory_operand" "+Q,S") + (match_operand 1 "const_int_operand" "n,n") +@@ -2819,10 +3351,11 @@ + int size = INTVAL (operands[1]) / BITS_PER_UNIT; + + operands[1] = GEN_INT ((1ul << size) - 1); +- return (which_alternative == 0) ? "stcm\t%2,%1,%S0" ++ return (which_alternative == 0) ? "stcm\t%2,%1,%S0" + : "stcmy\t%2,%1,%S0"; + } +- [(set_attr "op_type" "RS,RSY")]) ++ [(set_attr "op_type" "RS,RSY") ++ (set_attr "z10prop" "z10_super,z10_super")]) + + (define_insn "*insvdi_mem_reghigh" + [(set (zero_extract:DI (match_operand:QI 0 "memory_operand" "+QS") +@@ -2840,7 +3373,8 @@ + operands[1] = GEN_INT ((1ul << size) - 1); + return "stcmh\t%2,%1,%S0"; + } +-[(set_attr "op_type" "RSY")]) ++[(set_attr "op_type" "RSY") ++ (set_attr "z10prop" "z10_super")]) + + (define_insn "*insv<mode>_reg_imm" + [(set (zero_extract:P (match_operand:P 0 "register_operand" "+d") +@@ -2861,8 +3395,10 @@ + default: gcc_unreachable(); + } + } +- [(set_attr "op_type" "RI")]) ++ [(set_attr "op_type" "RI") ++ (set_attr "z10prop" "z10_super_E1")]) + ++ + (define_insn "*insv<mode>_reg_extimm" + [(set (zero_extract:P (match_operand:P 0 "register_operand" "+d") + (const_int 32) +@@ -2880,8 +3416,10 @@ + default: gcc_unreachable(); + } + } +- [(set_attr "op_type" "RIL")]) ++ [(set_attr "op_type" "RIL") ++ (set_attr "z10prop" "z10_fwd_E1")]) + ++ + ; + ; extendsidi2 instruction pattern(s). + ; +@@ -2902,13 +3440,17 @@ + }) + + (define_insn "*extendsidi2" +- [(set (match_operand:DI 0 "register_operand" "=d,d") +- (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m")))] ++ [(set (match_operand:DI 0 "register_operand" "=d,d,d") ++ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,RT,b")))] + "TARGET_64BIT" + "@ + lgfr\t%0,%1 +- lgf\t%0,%1" +- [(set_attr "op_type" "RRE,RXY")]) ++ lgf\t%0,%1 ++ lgfrl\t%0,%1" ++ [(set_attr "op_type" "RRE,RXY,RIL") ++ (set_attr "type" "*,*,larl") ++ (set_attr "cpu_facility" "*,*,z10") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")]) + + ; + ; extend(hi|qi)(si|di)2 instruction pattern(s). +@@ -2943,34 +3485,43 @@ + ; + + (define_insn "*extendhidi2_extimm" +- [(set (match_operand:DI 0 "register_operand" "=d,d") +- (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))] ++ [(set (match_operand:DI 0 "register_operand" "=d,d,d") ++ (sign_extend:DI (match_operand:HI 1 "general_operand" "d,RT,b")))] + "TARGET_64BIT && TARGET_EXTIMM" + "@ + lghr\t%0,%1 +- lgh\t%0,%1" +- [(set_attr "op_type" "RRE,RXY")]) ++ lgh\t%0,%1 ++ lghrl\t%0,%1" ++ [(set_attr "op_type" "RRE,RXY,RIL") ++ (set_attr "type" "*,*,larl") ++ (set_attr "cpu_facility" "extimm,extimm,z10") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")]) + + (define_insn "*extendhidi2" + [(set (match_operand:DI 0 "register_operand" "=d") +- (sign_extend:DI (match_operand:HI 1 "memory_operand" "m")))] ++ (sign_extend:DI (match_operand:HI 1 "memory_operand" "RT")))] + "TARGET_64BIT" + "lgh\t%0,%1" +- [(set_attr "op_type" "RXY")]) ++ [(set_attr "op_type" "RXY") ++ (set_attr "z10prop" "z10_super_E1")]) + + ; + ; extendhisi2 instruction pattern(s). + ; + + (define_insn "*extendhisi2_extimm" +- [(set (match_operand:SI 0 "register_operand" "=d,d,d") +- (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,T")))] ++ [(set (match_operand:SI 0 "register_operand" "=d,d,d,d") ++ (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" " d,R,T,b")))] + "TARGET_EXTIMM" + "@ + lhr\t%0,%1 + lh\t%0,%1 +- lhy\t%0,%1" +- [(set_attr "op_type" "RRE,RX,RXY")]) ++ lhy\t%0,%1 ++ lhrl\t%0,%1" ++ [(set_attr "op_type" "RRE,RX,RXY,RIL") ++ (set_attr "type" "*,*,*,larl") ++ (set_attr "cpu_facility" "extimm,extimm,extimm,z10") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,z10_super_E1")]) + + (define_insn "*extendhisi2" + [(set (match_operand:SI 0 "register_operand" "=d,d") +@@ -2979,7 +3530,8 @@ + "@ + lh\t%0,%1 + lhy\t%0,%1" +- [(set_attr "op_type" "RX,RXY")]) ++ [(set_attr "op_type" "RX,RXY") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1")]) + + ; + ; extendqi(si|di)2 instruction pattern(s). +@@ -2988,20 +3540,22 @@ + ; lbr, lgbr, lb, lgb + (define_insn "*extendqi<mode>2_extimm" + [(set (match_operand:GPR 0 "register_operand" "=d,d") +- (sign_extend:GPR (match_operand:QI 1 "nonimmediate_operand" "d,m")))] ++ (sign_extend:GPR (match_operand:QI 1 "nonimmediate_operand" "d,RT")))] + "TARGET_EXTIMM" + "@ + l<g>br\t%0,%1 + l<g>b\t%0,%1" +- [(set_attr "op_type" "RRE,RXY")]) ++ [(set_attr "op_type" "RRE,RXY") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1")]) + + ; lb, lgb + (define_insn "*extendqi<mode>2" + [(set (match_operand:GPR 0 "register_operand" "=d") +- (sign_extend:GPR (match_operand:QI 1 "memory_operand" "m")))] ++ (sign_extend:GPR (match_operand:QI 1 "memory_operand" "RT")))] + "!TARGET_EXTIMM && TARGET_LONG_DISPLACEMENT" + "l<g>b\t%0,%1" +- [(set_attr "op_type" "RXY")]) ++ [(set_attr "op_type" "RXY") ++ (set_attr "z10prop" "z10_super_E1")]) + + (define_insn_and_split "*extendqi<mode>2_short_displ" + [(set (match_operand:GPR 0 "register_operand" "=d") +@@ -3042,13 +3596,17 @@ + }) + + (define_insn "*zero_extendsidi2" +- [(set (match_operand:DI 0 "register_operand" "=d,d") +- (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,m")))] ++ [(set (match_operand:DI 0 "register_operand" "=d,d,d") ++ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "d,RT,b")))] + "TARGET_64BIT" + "@ + llgfr\t%0,%1 +- llgf\t%0,%1" +- [(set_attr "op_type" "RRE,RXY")]) ++ llgf\t%0,%1 ++ llgfrl\t%0,%1" ++ [(set_attr "op_type" "RRE,RXY,RIL") ++ (set_attr "type" "*,*,larl") ++ (set_attr "cpu_facility" "*,*,z10") ++ (set_attr "z10prop" "z10_fwd_E1,z10_fwd_A3,z10_fwd_A3")]) + + ; + ; LLGT-type instructions (zero-extend from 31 bit to 64 bit). +@@ -3056,15 +3614,16 @@ + + (define_insn "*llgt_sidi" + [(set (match_operand:DI 0 "register_operand" "=d") +- (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "m") 0) ++ (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "RT") 0) + (const_int 2147483647)))] + "TARGET_64BIT" + "llgt\t%0,%1" +- [(set_attr "op_type" "RXE")]) ++ [(set_attr "op_type" "RXE") ++ (set_attr "z10prop" "z10_super_E1")]) + + (define_insn_and_split "*llgt_sidi_split" + [(set (match_operand:DI 0 "register_operand" "=d") +- (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "m") 0) ++ (and:DI (subreg:DI (match_operand:SI 1 "memory_operand" "RT") 0) + (const_int 2147483647))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_64BIT" +@@ -3077,13 +3636,14 @@ + + (define_insn "*llgt_sisi" + [(set (match_operand:SI 0 "register_operand" "=d,d") +- (and:SI (match_operand:SI 1 "nonimmediate_operand" "d,m") ++ (and:SI (match_operand:SI 1 "nonimmediate_operand" "d,RT") + (const_int 2147483647)))] + "TARGET_ZARCH" + "@ + llgtr\t%0,%1 + llgt\t%0,%1" +- [(set_attr "op_type" "RRE,RXE")]) ++ [(set_attr "op_type" "RRE,RXE") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1")]) + + (define_insn "*llgt_didi" + [(set (match_operand:DI 0 "register_operand" "=d,d") +@@ -3093,7 +3653,8 @@ + "@ + llgtr\t%0,%1 + llgt\t%0,%N1" +- [(set_attr "op_type" "RRE,RXE")]) ++ [(set_attr "op_type" "RRE,RXE") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1")]) + + (define_split + [(set (match_operand:GPR 0 "register_operand" "") +@@ -3124,7 +3685,7 @@ + } + else if (!TARGET_EXTIMM) + { +- rtx bitcount = GEN_INT (GET_MODE_BITSIZE(DImode) - ++ rtx bitcount = GEN_INT (GET_MODE_BITSIZE(DImode) - + GET_MODE_BITSIZE(<MODE>mode)); + operands[1] = gen_lowpart (DImode, operands[1]); + emit_insn (gen_ashldi3 (operands[0], operands[1], bitcount)); +@@ -3141,29 +3702,45 @@ + if (!TARGET_EXTIMM) + { + operands[1] = gen_lowpart (SImode, operands[1]); +- emit_insn (gen_andsi3 (operands[0], operands[1], ++ emit_insn (gen_andsi3 (operands[0], operands[1], + GEN_INT ((1 << GET_MODE_BITSIZE(<MODE>mode)) - 1))); + DONE; + } + }) + ++; llhrl, llghrl ++(define_insn "*zero_extendhi<mode>2_z10" ++ [(set (match_operand:GPR 0 "register_operand" "=d,d,d") ++ (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "d,RT,b")))] ++ "TARGET_Z10" ++ "@ ++ ll<g>hr\t%0,%1 ++ ll<g>h\t%0,%1 ++ ll<g>hrl\t%0,%1" ++ [(set_attr "op_type" "RXY,RRE,RIL") ++ (set_attr "type" "*,*,larl") ++ (set_attr "cpu_facility" "*,*,z10") ++ (set_attr "z10prop" "z10_fwd_A3")]) ++ + ; llhr, llcr, llghr, llgcr, llh, llc, llgh, llgc + (define_insn "*zero_extend<HQI:mode><GPR:mode>2_extimm" + [(set (match_operand:GPR 0 "register_operand" "=d,d") +- (zero_extend:GPR (match_operand:HQI 1 "nonimmediate_operand" "d,m")))] ++ (zero_extend:GPR (match_operand:HQI 1 "nonimmediate_operand" "d,RT")))] + "TARGET_EXTIMM" + "@ + ll<g><hc>r\t%0,%1 + ll<g><hc>\t%0,%1" +- [(set_attr "op_type" "RRE,RXY")]) ++ [(set_attr "op_type" "RRE,RXY") ++ (set_attr "z10prop" "z10_super_E1,z10_fwd_A3")]) + + ; llgh, llgc + (define_insn "*zero_extend<HQI:mode><GPR:mode>2" + [(set (match_operand:GPR 0 "register_operand" "=d") +- (zero_extend:GPR (match_operand:HQI 1 "memory_operand" "m")))] ++ (zero_extend:GPR (match_operand:HQI 1 "memory_operand" "RT")))] + "TARGET_ZARCH && !TARGET_EXTIMM" + "llg<hc>\t%0,%1" +- [(set_attr "op_type" "RXY")]) ++ [(set_attr "op_type" "RXY") ++ (set_attr "z10prop" "z10_fwd_A3")]) + + (define_insn_and_split "*zero_extendhisi2_31" + [(set (match_operand:SI 0 "register_operand" "=&d") +@@ -3180,7 +3757,7 @@ + + (define_insn_and_split "*zero_extendqisi2_31" + [(set (match_operand:SI 0 "register_operand" "=&d") +- (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))] ++ (zero_extend:SI (match_operand:QI 1 "memory_operand" "RT")))] + "!TARGET_ZARCH" + "#" + "&& reload_completed" +@@ -3204,14 +3781,15 @@ + + (define_insn "*zero_extendqihi2_64" + [(set (match_operand:HI 0 "register_operand" "=d") +- (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))] ++ (zero_extend:HI (match_operand:QI 1 "memory_operand" "RT")))] + "TARGET_ZARCH && !TARGET_EXTIMM" + "llgc\t%0,%1" +- [(set_attr "op_type" "RXY")]) ++ [(set_attr "op_type" "RXY") ++ (set_attr "z10prop" "z10_fwd_A3")]) + + (define_insn_and_split "*zero_extendqihi2_31" + [(set (match_operand:HI 0 "register_operand" "=&d") +- (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))] ++ (zero_extend:HI (match_operand:QI 1 "memory_operand" "RT")))] + "!TARGET_ZARCH" + "#" + "&& reload_completed" +@@ -3228,8 +3806,8 @@ + [(set (match_operand:DI 0 "register_operand" "") + (unsigned_fix:DI (match_operand:DD 1 "register_operand" ""))) + (clobber (match_scratch:TD 2 "=f"))])] +- +- "TARGET_HARD_FLOAT && TARGET_HARD_DFP" ++ ++ "TARGET_HARD_DFP" + { + rtx label1 = gen_label_rtx (); + rtx label2 = gen_label_rtx (); +@@ -3240,7 +3818,7 @@ + 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 ++ 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); +@@ -3261,17 +3839,17 @@ + (define_expand "fixuns_trunctddi2" + [(set (match_operand:DI 0 "register_operand" "") + (unsigned_fix:DI (match_operand:TD 1 "register_operand" "")))] +- "TARGET_HARD_FLOAT && TARGET_HARD_DFP" ++ "TARGET_HARD_DFP" + { + rtx label1 = gen_label_rtx (); + rtx label2 = gen_label_rtx (); + rtx temp = gen_reg_rtx (TDmode); + REAL_VALUE_TYPE cmp, sub; +- ++ + operands[1] = force_reg (TDmode, operands[1]); + decimal_real_from_string (&cmp, "9223372036854775808.0"); /* 2^63 */ + decimal_real_from_string (&sub, "18446744073709551616.0"); /* 2^64 */ +- ++ + emit_insn (gen_cmptd (operands[1], + CONST_DOUBLE_FROM_REAL_VALUE (cmp, TDmode))); + emit_jump_insn (gen_blt (label1)); +@@ -3287,7 +3865,7 @@ + }) + + ; +-; fixuns_trunc(sf|df)(si|di)2 and fix_trunc(sf|df)(si|di)2 ++; fixuns_trunc(sf|df)(si|di)2 and fix_trunc(sf|df)(si|di)2 + ; instruction pattern(s). + ; + +@@ -3300,11 +3878,11 @@ + rtx label2 = gen_label_rtx (); + rtx temp = gen_reg_rtx (<BFP:MODE>mode); + REAL_VALUE_TYPE cmp, sub; +- ++ + operands[1] = force_reg (<BFP:MODE>mode, operands[1]); + real_2expN (&cmp, GET_MODE_BITSIZE(<GPR:MODE>mode) - 1, <BFP:MODE>mode); + real_2expN (&sub, GET_MODE_BITSIZE(<GPR:MODE>mode), <BFP:MODE>mode); +- ++ + emit_insn (gen_cmp<BFP:mode> (operands[1], + CONST_DOUBLE_FROM_REAL_VALUE (cmp, <BFP:MODE>mode))); + emit_jump_insn (gen_blt (label1)); +@@ -3350,7 +3928,7 @@ + (define_expand "fix_trunc<mode>di2" + [(set (match_operand:DI 0 "register_operand" "") + (fix:DI (match_operand:DFP 1 "nonimmediate_operand" "")))] +- "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_HARD_DFP" ++ "TARGET_64BIT && TARGET_HARD_DFP" + { + operands[1] = force_reg (<MODE>mode, operands[1]); + emit_insn (gen_fix_trunc<mode>di2_dfp (operands[0], operands[1], +@@ -3364,10 +3942,10 @@ + (fix:DI (match_operand:DFP 1 "register_operand" "f"))) + (unspec:DI [(match_operand:DI 2 "immediate_operand" "K")] UNSPEC_ROUND) + (clobber (reg:CC CC_REGNUM))] +- "TARGET_64BIT && TARGET_HARD_FLOAT && TARGET_HARD_DFP" ++ "TARGET_64BIT && TARGET_HARD_DFP" + "cg<DFP:xde>tr\t%0,%h2,%1" + [(set_attr "op_type" "RRF") +- (set_attr "type" "ftoi")]) ++ (set_attr "type" "ftoidfp")]) + + + ; +@@ -3394,7 +3972,7 @@ + "TARGET_64BIT && TARGET_HARD_FLOAT" + "c<xde>g<bt>r\t%0,%1" + [(set_attr "op_type" "RRE") +- (set_attr "type" "itof" )]) ++ (set_attr "type" "itof<mode>" )]) + + ; cxfbr, cdfbr, cefbr + (define_insn "floatsi<mode>2" +@@ -3403,7 +3981,7 @@ + "TARGET_HARD_FLOAT" + "c<xde>fbr\t%0,%1" + [(set_attr "op_type" "RRE") +- (set_attr "type" "itof" )]) ++ (set_attr "type" "itof<mode>" )]) + + + ; +@@ -3430,7 +4008,7 @@ + "TARGET_HARD_FLOAT" + "l<xde>xbr\t%2,%1\;l<xde>r\t%0,%2" + [(set_attr "length" "6") +- (set_attr "type" "ftrunctf")]) ++ (set_attr "type" "ftrunctf")]) + + ; + ; trunctddd2 and truncddsd2 instruction pattern(s). +@@ -3440,18 +4018,18 @@ + [(set (match_operand:DD 0 "register_operand" "=f") + (float_truncate:DD (match_operand:TD 1 "register_operand" "f"))) + (clobber (match_scratch:TD 2 "=f"))] +- "TARGET_HARD_FLOAT && TARGET_HARD_DFP" ++ "TARGET_HARD_DFP" + "ldxtr\t%2,0,%1,0\;ldr\t%0,%2" + [(set_attr "length" "6") +- (set_attr "type" "ftrunctf")]) ++ (set_attr "type" "ftruncdd")]) + + (define_insn "truncddsd2" + [(set (match_operand:SD 0 "register_operand" "=f") + (float_truncate:SD (match_operand:DD 1 "register_operand" "f")))] +- "TARGET_HARD_FLOAT && TARGET_HARD_DFP" ++ "TARGET_HARD_DFP" + "ledtr\t%0,0,%1,0" + [(set_attr "op_type" "RRF") +- (set_attr "type" "fsimptf")]) ++ (set_attr "type" "ftruncsd")]) + + ; + ; extend(sf|df)(df|tf)2 instruction pattern(s). +@@ -3476,7 +4054,7 @@ + (define_insn "extendddtd2" + [(set (match_operand:TD 0 "register_operand" "=f") + (float_extend:TD (match_operand:DD 1 "register_operand" "f")))] +- "TARGET_HARD_FLOAT && TARGET_HARD_DFP" ++ "TARGET_HARD_DFP" + "lxdtr\t%0,%1,0" + [(set_attr "op_type" "RRF") + (set_attr "type" "fsimptf")]) +@@ -3484,7 +4062,7 @@ + (define_insn "extendsddd2" + [(set (match_operand:DD 0 "register_operand" "=f") + (float_extend:DD (match_operand:SD 1 "register_operand" "f")))] +- "TARGET_HARD_FLOAT && TARGET_HARD_DFP" ++ "TARGET_HARD_DFP" + "ldetr\t%0,%1,0" + [(set_attr "op_type" "RRF") + (set_attr "type" "fsimptf")]) +@@ -3497,7 +4075,7 @@ + (float_truncate:DFP_ALL (reg:BFP FPR2_REGNUM))) + (use (reg:SI GPR0_REGNUM)) + (clobber (reg:CC CC_REGNUM))] +- "TARGET_HARD_FLOAT && TARGET_DFP" ++ "TARGET_HARD_DFP" + "pfpo") + + (define_insn "*trunc<DFP_ALL:mode><BFP:mode>2" +@@ -3505,7 +4083,7 @@ + (float_truncate:BFP (reg:DFP_ALL FPR2_REGNUM))) + (use (reg:SI GPR0_REGNUM)) + (clobber (reg:CC CC_REGNUM))] +- "TARGET_HARD_FLOAT && TARGET_DFP" ++ "TARGET_HARD_DFP" + "pfpo") + + (define_expand "trunc<BFP:mode><DFP_ALL:mode>2" +@@ -3518,7 +4096,7 @@ + (clobber (reg:CC CC_REGNUM))]) + (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "") + (reg:DFP_ALL FPR0_REGNUM))] +- "TARGET_HARD_FLOAT && TARGET_DFP ++ "TARGET_HARD_DFP + && GET_MODE_SIZE (<BFP:MODE>mode) > GET_MODE_SIZE (<DFP_ALL:MODE>mode)" + { + HOST_WIDE_INT flags; +@@ -3539,7 +4117,7 @@ + (use (reg:SI GPR0_REGNUM)) + (clobber (reg:CC CC_REGNUM))]) + (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))] +- "TARGET_HARD_FLOAT && TARGET_DFP ++ "TARGET_HARD_DFP + && GET_MODE_SIZE (<DFP_ALL:MODE>mode) >= GET_MODE_SIZE (<BFP:MODE>mode)" + { + HOST_WIDE_INT flags; +@@ -3559,14 +4137,14 @@ + [(set (reg:DFP_ALL FPR0_REGNUM) (float_extend:DFP_ALL (reg:BFP FPR2_REGNUM))) + (use (reg:SI GPR0_REGNUM)) + (clobber (reg:CC CC_REGNUM))] +- "TARGET_HARD_FLOAT && TARGET_DFP" ++ "TARGET_HARD_DFP" + "pfpo") + + (define_insn "*extend<DFP_ALL:mode><BFP:mode>2" + [(set (reg:BFP FPR0_REGNUM) (float_extend:BFP (reg:DFP_ALL FPR2_REGNUM))) + (use (reg:SI GPR0_REGNUM)) + (clobber (reg:CC CC_REGNUM))] +- "TARGET_HARD_FLOAT && TARGET_DFP" ++ "TARGET_HARD_DFP" + "pfpo") + + (define_expand "extend<BFP:mode><DFP_ALL:mode>2" +@@ -3579,7 +4157,7 @@ + (clobber (reg:CC CC_REGNUM))]) + (set (match_operand:DFP_ALL 0 "nonimmediate_operand" "") + (reg:DFP_ALL FPR0_REGNUM))] +- "TARGET_HARD_FLOAT && TARGET_DFP ++ "TARGET_HARD_DFP + && GET_MODE_SIZE (<BFP:MODE>mode) <= GET_MODE_SIZE (<DFP_ALL:MODE>mode)" + { + HOST_WIDE_INT flags; +@@ -3600,7 +4178,7 @@ + (use (reg:SI GPR0_REGNUM)) + (clobber (reg:CC CC_REGNUM))]) + (set (match_operand:BFP 0 "nonimmediate_operand" "") (reg:BFP FPR0_REGNUM))] +- "TARGET_HARD_FLOAT && TARGET_DFP ++ "TARGET_HARD_DFP + && GET_MODE_SIZE (<DFP_ALL:MODE>mode) < GET_MODE_SIZE (<BFP:MODE>mode)" + { + HOST_WIDE_INT flags; +@@ -3659,7 +4237,7 @@ + + (define_expand "adddi3" + [(parallel +- [(set (match_operand:DI 0 "register_operand" "") ++ [(set (match_operand:DI 0 "nonimmediate_operand" "") + (plus:DI (match_operand:DI 1 "nonimmediate_operand" "") + (match_operand:DI 2 "general_operand" ""))) + (clobber (reg:CC CC_REGNUM))])] +@@ -3668,7 +4246,7 @@ + + (define_insn "*adddi3_sign" + [(set (match_operand:DI 0 "register_operand" "=d,d") +- (plus:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,m")) ++ (plus:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,RT")) + (match_operand:DI 1 "register_operand" "0,0"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_64BIT" +@@ -3679,7 +4257,7 @@ + + (define_insn "*adddi3_zero_cc" + [(set (reg CC_REGNUM) +- (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m")) ++ (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,RT")) + (match_operand:DI 1 "register_operand" "0,0")) + (const_int 0))) + (set (match_operand:DI 0 "register_operand" "=d,d") +@@ -3688,11 +4266,12 @@ + "@ + algfr\t%0,%2 + algf\t%0,%2" +- [(set_attr "op_type" "RRE,RXY")]) ++ [(set_attr "op_type" "RRE,RXY") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1")]) + + (define_insn "*adddi3_zero_cconly" + [(set (reg CC_REGNUM) +- (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m")) ++ (compare (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,RT")) + (match_operand:DI 1 "register_operand" "0,0")) + (const_int 0))) + (clobber (match_scratch:DI 0 "=d,d"))] +@@ -3700,21 +4279,23 @@ + "@ + algfr\t%0,%2 + algf\t%0,%2" +- [(set_attr "op_type" "RRE,RXY")]) ++ [(set_attr "op_type" "RRE,RXY") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1")]) + + (define_insn "*adddi3_zero" + [(set (match_operand:DI 0 "register_operand" "=d,d") +- (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m")) ++ (plus:DI (zero_extend:DI (match_operand:SI 2 "general_operand" "d,RT")) + (match_operand:DI 1 "register_operand" "0,0"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_64BIT" + "@ + algfr\t%0,%2 + algf\t%0,%2" +- [(set_attr "op_type" "RRE,RXY")]) ++ [(set_attr "op_type" "RRE,RXY") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1")]) + + (define_insn_and_split "*adddi3_31z" +- [(set (match_operand:DI 0 "register_operand" "=&d") ++ [(set (match_operand:DI 0 "nonimmediate_operand" "=&d") + (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0") + (match_operand:DI 2 "general_operand" "do") ) ) + (clobber (reg:CC CC_REGNUM))] +@@ -3739,7 +4320,7 @@ + operands[8] = operand_subword (operands[2], 1, 0, DImode);") + + (define_insn_and_split "*adddi3_31" +- [(set (match_operand:DI 0 "register_operand" "=&d") ++ [(set (match_operand:DI 0 "nonimmediate_operand" "=&d") + (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0") + (match_operand:DI 2 "general_operand" "do") ) ) + (clobber (reg:CC CC_REGNUM))] +@@ -3776,7 +4357,7 @@ + + (define_expand "addsi3" + [(parallel +- [(set (match_operand:SI 0 "register_operand" "") ++ [(set (match_operand:SI 0 "nonimmediate_operand" "") + (plus:SI (match_operand:SI 1 "nonimmediate_operand" "") + (match_operand:SI 2 "general_operand" ""))) + (clobber (reg:CC CC_REGNUM))])] +@@ -3798,11 +4379,11 @@ + ; add(di|si)3 instruction pattern(s). + ; + +-; ar, ahi, alfi, slfi, a, ay, agr, aghi, algfi, slgfi, ag ++; ar, ahi, alfi, slfi, a, ay, agr, aghi, algfi, slgfi, ag, asi, agsi + (define_insn "*add<mode>3" +- [(set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d,d") +- (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0,0") +- (match_operand:GPR 2 "general_operand" "d,K,Op,On,R,T") ) ) ++ [(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") ) ) + (clobber (reg:CC CC_REGNUM))] + "" + "@ +@@ -3811,16 +4392,25 @@ + al<g>fi\t%0,%2 + sl<g>fi\t%0,%n2 + a<g>\t%0,%2 +- a<y>\t%0,%2" +- [(set_attr "op_type" "RR<E>,RI,RIL,RIL,RX<Y>,RXY")]) ++ a<y>\t%0,%2 ++ a<g>si\t%0,%c2" ++ [(set_attr "op_type" "RR<E>,RI,RIL,RIL,RX<Y>,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")]) + +-; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg ++; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi + (define_insn "*add<mode>3_carry1_cc" + [(set (reg CC_REGNUM) +- (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0") +- (match_operand:GPR 2 "general_operand" "d,Op,On,R,T")) ++ (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")) + (match_dup 1))) +- (set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d") ++ (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d,d,d") + (plus:GPR (match_dup 1) (match_dup 2)))] + "s390_match_ccmode (insn, CCL1mode)" + "@ +@@ -3828,8 +4418,16 @@ + al<g>fi\t%0,%2 + sl<g>fi\t%0,%n2 + al<g>\t%0,%2 +- al<y>\t%0,%2" +- [(set_attr "op_type" "RR<E>,RIL,RIL,RX<Y>,RXY")]) ++ al<y>\t%0,%2 ++ al<g>si\t%0,%c2" ++ [(set_attr "op_type" "RR<E>,RIL,RIL,RX<Y>,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")]) + + ; alr, al, aly, algr, alg + (define_insn "*add<mode>3_carry1_cconly" +@@ -3843,15 +4441,16 @@ + al<g>r\t%0,%2 + al<g>\t%0,%2 + al<y>\t%0,%2" +- [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) ++ [(set_attr "op_type" "RR<E>,RX<Y>,RXY") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")]) + +-; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg ++; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi + (define_insn "*add<mode>3_carry2_cc" + [(set (reg CC_REGNUM) +- (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0") +- (match_operand:GPR 2 "general_operand" "d,Op,On,R,T")) ++ (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")) + (match_dup 2))) +- (set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d") ++ (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d,d,RS") + (plus:GPR (match_dup 1) (match_dup 2)))] + "s390_match_ccmode (insn, CCL1mode)" + "@ +@@ -3859,8 +4458,16 @@ + al<g>fi\t%0,%2 + sl<g>fi\t%0,%n2 + al<g>\t%0,%2 +- al<y>\t%0,%2" +- [(set_attr "op_type" "RR<E>,RIL,RIL,RX<Y>,RXY")]) ++ al<y>\t%0,%2 ++ al<g>si\t%0,%c2" ++ [(set_attr "op_type" "RR<E>,RIL,RIL,RX<Y>,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")]) + + ; alr, al, aly, algr, alg + (define_insn "*add<mode>3_carry2_cconly" +@@ -3874,15 +4481,16 @@ + al<g>r\t%0,%2 + al<g>\t%0,%2 + al<y>\t%0,%2" +- [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) ++ [(set_attr "op_type" "RR<E>,RX<Y>,RXY") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")]) + +-; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg ++; alr, alfi, slfi, al, aly, algr, algfi, slgfi, alg, alsi, algsi + (define_insn "*add<mode>3_cc" + [(set (reg CC_REGNUM) +- (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0,0,0,0") +- (match_operand:GPR 2 "general_operand" "d,Op,On,R,T")) ++ (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")) + (const_int 0))) +- (set (match_operand:GPR 0 "register_operand" "=d,d,d,d,d") ++ (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d,d,RS") + (plus:GPR (match_dup 1) (match_dup 2)))] + "s390_match_ccmode (insn, CCLmode)" + "@ +@@ -3890,8 +4498,16 @@ + al<g>fi\t%0,%2 + sl<g>fi\t%0,%n2 + al<g>\t%0,%2 +- al<y>\t%0,%2" +- [(set_attr "op_type" "RR<E>,RIL,RIL,RX<Y>,RXY")]) ++ al<y>\t%0,%2 ++ al<g>si\t%0,%c2" ++ [(set_attr "op_type" "RR<E>,RIL,RIL,RX<Y>,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")]) + + ; alr, al, aly, algr, alg + (define_insn "*add<mode>3_cconly" +@@ -3905,7 +4521,8 @@ + al<g>r\t%0,%2 + al<g>\t%0,%2 + al<y>\t%0,%2" +- [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) ++ [(set_attr "op_type" "RR<E>,RX<Y>,RXY") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")]) + + ; alr, al, aly, algr, alg + (define_insn "*add<mode>3_cconly2" +@@ -3918,24 +4535,29 @@ + al<g>r\t%0,%2 + al<g>\t%0,%2 + al<y>\t%0,%2" +- [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) ++ [(set_attr "op_type" "RR<E>,RX<Y>,RXY") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1")]) + +-; ahi, afi, aghi, agfi ++; ahi, afi, aghi, agfi, asi, agsi + (define_insn "*add<mode>3_imm_cc" + [(set (reg CC_REGNUM) +- (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0") +- (match_operand:GPR 2 "const_int_operand" "K,Os")) ++ (compare (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0,0") ++ (match_operand:GPR 2 "const_int_operand" "K,Os,C")) + (const_int 0))) +- (set (match_operand:GPR 0 "register_operand" "=d,d") ++ (set (match_operand:GPR 0 "nonimmediate_operand" "=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\") +- || CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'O', \"Os\")) ++ || CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'O', \"Os\") ++ || CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'C', \"C\")) + && INTVAL (operands[2]) != -((HOST_WIDE_INT)1 << (GET_MODE_BITSIZE(<MODE>mode) - 1))" + "@ + a<g>hi\t%0,%h2 +- a<g>fi\t%0,%2" +- [(set_attr "op_type" "RI,RIL")]) ++ a<g>fi\t%0,%2 ++ a<g>si\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")]) + + ; + ; add(tf|df|sf|td|dd)3 instruction pattern(s). +@@ -3952,7 +4574,7 @@ + a<xde><bt>r\t%0,<op1>%2 + a<xde>b\t%0,%2" + [(set_attr "op_type" "<RRer>,RXE") +- (set_attr "type" "fsimp<bfp>")]) ++ (set_attr "type" "fsimp<mode>")]) + + ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr + (define_insn "*add<mode>3_cc" +@@ -3967,7 +4589,7 @@ + a<xde><bt>r\t%0,<op1>%2 + a<xde>b\t%0,%2" + [(set_attr "op_type" "<RRer>,RXE") +- (set_attr "type" "fsimp<bfp>")]) ++ (set_attr "type" "fsimp<mode>")]) + + ; axbr, adbr, aebr, axb, adb, aeb, adtr, axtr + (define_insn "*add<mode>3_cconly" +@@ -3981,7 +4603,7 @@ + a<xde><bt>r\t%0,<op1>%2 + a<xde>b\t%0,%2" + [(set_attr "op_type" "<RRer>,RXE") +- (set_attr "type" "fsimp<bfp>")]) ++ (set_attr "type" "fsimp<mode>")]) + + + ;; +@@ -4032,18 +4654,19 @@ + (define_insn "*subdi3_sign" + [(set (match_operand:DI 0 "register_operand" "=d,d") + (minus:DI (match_operand:DI 1 "register_operand" "0,0") +- (sign_extend:DI (match_operand:SI 2 "general_operand" "d,m")))) ++ (sign_extend:DI (match_operand:SI 2 "general_operand" "d,RT")))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_64BIT" + "@ + sgfr\t%0,%2 + sgf\t%0,%2" +- [(set_attr "op_type" "RRE,RXY")]) ++ [(set_attr "op_type" "RRE,RXY") ++ (set_attr "z10prop" "z10_c,*")]) + + (define_insn "*subdi3_zero_cc" + [(set (reg CC_REGNUM) + (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0") +- (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m"))) ++ (zero_extend:DI (match_operand:SI 2 "general_operand" "d,RT"))) + (const_int 0))) + (set (match_operand:DI 0 "register_operand" "=d,d") + (minus:DI (match_dup 1) (zero_extend:DI (match_dup 2))))] +@@ -4051,30 +4674,33 @@ + "@ + slgfr\t%0,%2 + slgf\t%0,%2" +- [(set_attr "op_type" "RRE,RXY")]) ++ [(set_attr "op_type" "RRE,RXY") ++ (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")]) + + (define_insn "*subdi3_zero_cconly" + [(set (reg CC_REGNUM) + (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0") +- (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m"))) ++ (zero_extend:DI (match_operand:SI 2 "general_operand" "d,RT"))) + (const_int 0))) + (clobber (match_scratch:DI 0 "=d,d"))] + "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT" + "@ + slgfr\t%0,%2 + slgf\t%0,%2" +- [(set_attr "op_type" "RRE,RXY")]) ++ [(set_attr "op_type" "RRE,RXY") ++ (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")]) + + (define_insn "*subdi3_zero" + [(set (match_operand:DI 0 "register_operand" "=d,d") + (minus:DI (match_operand:DI 1 "register_operand" "0,0") +- (zero_extend:DI (match_operand:SI 2 "general_operand" "d,m")))) ++ (zero_extend:DI (match_operand:SI 2 "general_operand" "d,RT")))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_64BIT" + "@ + slgfr\t%0,%2 + slgf\t%0,%2" +- [(set_attr "op_type" "RRE,RXY")]) ++ [(set_attr "op_type" "RRE,RXY") ++ (set_attr "z10prop" "z10_super_c_E1,z10_super_E1")]) + + (define_insn_and_split "*subdi3_31z" + [(set (match_operand:DI 0 "register_operand" "=&d") +@@ -4171,7 +4797,8 @@ + s<g>r\t%0,%2 + s<g>\t%0,%2 + s<y>\t%0,%2" +- [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) ++ [(set_attr "op_type" "RR<E>,RX<Y>,RXY") ++ (set_attr "z10prop" "z10_super_c_E1,z10_super_E1,z10_super_E1")]) + + ; slr, sl, sly, slgr, slg + (define_insn "*sub<mode>3_borrow_cc" +@@ -4186,7 +4813,8 @@ + sl<g>r\t%0,%2 + sl<g>\t%0,%2 + sl<y>\t%0,%2" +- [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) ++ [(set_attr "op_type" "RR<E>,RX<Y>,RXY") ++ (set_attr "z10prop" "z10_super_c_E1,z10_super_E1,z10_super_E1")]) + + ; slr, sl, sly, slgr, slg + (define_insn "*sub<mode>3_borrow_cconly" +@@ -4200,7 +4828,8 @@ + sl<g>r\t%0,%2 + sl<g>\t%0,%2 + sl<y>\t%0,%2" +- [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) ++ [(set_attr "op_type" "RR<E>,RX<Y>,RXY") ++ (set_attr "z10prop" "z10_super_c_E1,z10_super_E1,z10_super_E1")]) + + ; slr, sl, sly, slgr, slg + (define_insn "*sub<mode>3_cc" +@@ -4215,7 +4844,8 @@ + sl<g>r\t%0,%2 + sl<g>\t%0,%2 + sl<y>\t%0,%2" +- [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) ++ [(set_attr "op_type" "RR<E>,RX<Y>,RXY") ++ (set_attr "z10prop" "z10_super_c_E1,z10_super_E1,z10_super_E1")]) + + ; slr, sl, sly, slgr, slg + (define_insn "*sub<mode>3_cc2" +@@ -4229,7 +4859,8 @@ + sl<g>r\t%0,%2 + sl<g>\t%0,%2 + sl<y>\t%0,%2" +- [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) ++ [(set_attr "op_type" "RR<E>,RX<Y>,RXY") ++ (set_attr "z10prop" "z10_super_c_E1,z10_super_E1,z10_super_E1")]) + + ; slr, sl, sly, slgr, slg + (define_insn "*sub<mode>3_cconly" +@@ -4243,8 +4874,10 @@ + sl<g>r\t%0,%2 + sl<g>\t%0,%2 + sl<y>\t%0,%2" +- [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) ++ [(set_attr "op_type" "RR<E>,RX<Y>,RXY") ++ (set_attr "z10prop" "z10_super_c_E1,z10_super_E1,z10_super_E1")]) + ++ + ; slr, sl, sly, slgr, slg + (define_insn "*sub<mode>3_cconly2" + [(set (reg CC_REGNUM) +@@ -4256,8 +4889,10 @@ + sl<g>r\t%0,%2 + sl<g>\t%0,%2 + sl<y>\t%0,%2" +- [(set_attr "op_type" "RR<E>,RX<Y>,RXY")]) ++ [(set_attr "op_type" "RR<E>,RX<Y>,RXY") ++ (set_attr "z10prop" "z10_super_c_E1,z10_super_E1,z10_super_E1")]) + ++ + ; + ; sub(tf|df|sf|td|dd)3 instruction pattern(s). + ; +@@ -4273,7 +4908,7 @@ + s<xde><bt>r\t%0,<op1>%2 + s<xde>b\t%0,%2" + [(set_attr "op_type" "<RRer>,RXE") +- (set_attr "type" "fsimp<bfp>")]) ++ (set_attr "type" "fsimp<mode>")]) + + ; sxbr, sdbr, sebr, sxb, sdb, seb, sxtr, sdtr + (define_insn "*sub<mode>3_cc" +@@ -4288,7 +4923,7 @@ + s<xde><bt>r\t%0,<op1>%2 + s<xde>b\t%0,%2" + [(set_attr "op_type" "<RRer>,RXE") +- (set_attr "type" "fsimp<bfp>")]) ++ (set_attr "type" "fsimp<mode>")]) + + ; sxbr, sdbr, sebr, sxb, sdb, seb, sxtr, sdtr + (define_insn "*sub<mode>3_cconly" +@@ -4302,7 +4937,7 @@ + s<xde><bt>r\t%0,<op1>%2 + s<xde>b\t%0,%2" + [(set_attr "op_type" "<RRer>,RXE") +- (set_attr "type" "fsimp<bfp>")]) ++ (set_attr "type" "fsimp<mode>")]) + + + ;; +@@ -4324,7 +4959,7 @@ + (compare + (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "") + (match_operand:GPR 1 "nonimmediate_operand" "%0,0")) +- (match_operand:GPR 2 "general_operand" "d,m")) ++ (match_operand:GPR 2 "general_operand" "d,RT")) + (match_dup 1))) + (set (match_operand:GPR 0 "register_operand" "=d,d") + (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))] +@@ -4340,7 +4975,7 @@ + (compare + (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "") + (match_operand:GPR 1 "nonimmediate_operand" "%0,0")) +- (match_operand:GPR 2 "general_operand" "d,m")) ++ (match_operand:GPR 2 "general_operand" "d,RT")) + (match_dup 1))) + (clobber (match_scratch:GPR 0 "=d,d"))] + "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH" +@@ -4357,7 +4992,7 @@ + (compare + (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "") + (match_operand:GPR 1 "nonimmediate_operand" "%0,0")) +- (match_operand:GPR 2 "general_operand" "d,m")) ++ (match_operand:GPR 2 "general_operand" "d,RT")) + (match_dup 2))) + (set (match_operand:GPR 0 "register_operand" "=d,d") + (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))] +@@ -4373,7 +5008,7 @@ + (compare + (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "") + (match_operand:GPR 1 "nonimmediate_operand" "%0,0")) +- (match_operand:GPR 2 "general_operand" "d,m")) ++ (match_operand:GPR 2 "general_operand" "d,RT")) + (match_dup 2))) + (clobber (match_scratch:GPR 0 "=d,d"))] + "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH" +@@ -4388,7 +5023,7 @@ + (compare + (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "") + (match_operand:GPR 1 "nonimmediate_operand" "%0,0")) +- (match_operand:GPR 2 "general_operand" "d,m")) ++ (match_operand:GPR 2 "general_operand" "d,RT")) + (const_int 0))) + (set (match_operand:GPR 0 "register_operand" "=d,d") + (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))] +@@ -4403,7 +5038,7 @@ + [(set (match_operand:GPR 0 "register_operand" "=d,d") + (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "") + (match_operand:GPR 1 "nonimmediate_operand" "%0,0")) +- (match_operand:GPR 2 "general_operand" "d,m"))) ++ (match_operand:GPR 2 "general_operand" "d,RT"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_CPU_ZARCH" + "@ +@@ -4416,7 +5051,7 @@ + [(set (reg CC_REGNUM) + (compare + (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0") +- (match_operand:GPR 2 "general_operand" "d,m")) ++ (match_operand:GPR 2 "general_operand" "d,RT")) + (match_operand:GPR 3 "s390_slb_comparison" "")) + (const_int 0))) + (set (match_operand:GPR 0 "register_operand" "=d,d") +@@ -4425,20 +5060,22 @@ + "@ + slb<g>r\t%0,%2 + slb<g>\t%0,%2" +- [(set_attr "op_type" "RRE,RXY")]) ++ [(set_attr "op_type" "RRE,RXY") ++ (set_attr "z10prop" "z10_c,*")]) + + ; slbr, slb, slbgr, slbg + (define_insn "*sub<mode>3_slb" + [(set (match_operand:GPR 0 "register_operand" "=d,d") + (minus:GPR (minus:GPR (match_operand:GPR 1 "nonimmediate_operand" "0,0") +- (match_operand:GPR 2 "general_operand" "d,m")) ++ (match_operand:GPR 2 "general_operand" "d,RT")) + (match_operand:GPR 3 "s390_slb_comparison" ""))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_CPU_ZARCH" + "@ + slb<g>r\t%0,%2 + slb<g>\t%0,%2" +- [(set_attr "op_type" "RRE,RXY")]) ++ [(set_attr "op_type" "RRE,RXY") ++ (set_attr "z10prop" "z10_c,*")]) + + (define_expand "add<mode>cc" + [(match_operand:GPR 0 "register_operand" "") +@@ -4446,9 +5083,9 @@ + (match_operand:GPR 2 "register_operand" "") + (match_operand:GPR 3 "const_int_operand" "")] + "TARGET_CPU_ZARCH" +- "if (!s390_expand_addcc (GET_CODE (operands[1]), +- s390_compare_op0, s390_compare_op1, +- operands[0], operands[2], ++ "if (!s390_expand_addcc (GET_CODE (operands[1]), ++ s390_compare_op0, s390_compare_op1, ++ operands[0], operands[2], + operands[3])) FAIL; DONE;") + + ; +@@ -4504,7 +5141,7 @@ + [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 1))) + (clobber (reg:CC CC_REGNUM))])] + "" +-{ ++{ + if (!s390_compare_emitted || GET_MODE (s390_compare_emitted) != CCZ1mode) + FAIL; + operands[1] = s390_emit_compare (NE, s390_compare_op0, s390_compare_op1); +@@ -4513,7 +5150,7 @@ + + (define_insn_and_split "*sne" + [(set (match_operand:SI 0 "register_operand" "=d") +- (ne:SI (match_operand:CCZ1 1 "register_operand" "0") ++ (ne:SI (match_operand:CCZ1 1 "register_operand" "0") + (const_int 0))) + (clobber (reg:CC CC_REGNUM))] + "" +@@ -4534,69 +5171,78 @@ + + (define_insn "*muldi3_sign" + [(set (match_operand:DI 0 "register_operand" "=d,d") +- (mult:DI (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "d,m")) ++ (mult:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,RT")) + (match_operand:DI 1 "register_operand" "0,0")))] + "TARGET_64BIT" + "@ + msgfr\t%0,%2 + msgf\t%0,%2" +- [(set_attr "op_type" "RRE,RXY") +- (set_attr "type" "imuldi")]) ++ [(set_attr "op_type" "RRE,RXY") ++ (set_attr "type" "imuldi")]) + + (define_insn "muldi3" +- [(set (match_operand:DI 0 "register_operand" "=d,d,d") +- (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0") +- (match_operand:DI 2 "general_operand" "d,K,m")))] ++ [(set (match_operand:DI 0 "register_operand" "=d,d,d,d") ++ (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0") ++ (match_operand:DI 2 "general_operand" "d,K,RT,Os")))] + "TARGET_64BIT" + "@ + msgr\t%0,%2 + mghi\t%0,%h2 +- msg\t%0,%2" +- [(set_attr "op_type" "RRE,RI,RXY") +- (set_attr "type" "imuldi")]) ++ msg\t%0,%2 ++ msgfi\t%0,%2" ++ [(set_attr "op_type" "RRE,RI,RXY,RIL") ++ (set_attr "type" "imuldi") ++ (set_attr "cpu_facility" "*,*,*,z10")]) + + ; + ; mulsi3 instruction pattern(s). + ; + + (define_insn "*mulsi3_sign" +- [(set (match_operand:SI 0 "register_operand" "=d") +- (mult:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R")) +- (match_operand:SI 1 "register_operand" "0")))] ++ [(set (match_operand:SI 0 "register_operand" "=d,d") ++ (mult:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T")) ++ (match_operand:SI 1 "register_operand" "0,0")))] + "" +- "mh\t%0,%2" +- [(set_attr "op_type" "RX") +- (set_attr "type" "imulhi")]) ++ "@ ++ mh\t%0,%2 ++ mhy\t%0,%2" ++ [(set_attr "op_type" "RX,RXY") ++ (set_attr "type" "imulhi") ++ (set_attr "cpu_facility" "*,z10")]) + + (define_insn "mulsi3" +- [(set (match_operand:SI 0 "register_operand" "=d,d,d,d") +- (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0") +- (match_operand:SI 2 "general_operand" "d,K,R,T")))] ++ [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d") ++ (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0") ++ (match_operand:SI 2 "general_operand" "d,K,R,T,Os")))] + "" + "@ + msr\t%0,%2 + mhi\t%0,%h2 + ms\t%0,%2 +- msy\t%0,%2" +- [(set_attr "op_type" "RRE,RI,RX,RXY") +- (set_attr "type" "imulsi,imulhi,imulsi,imulsi")]) ++ msy\t%0,%2 ++ msfi\t%0,%2" ++ [(set_attr "op_type" "RRE,RI,RX,RXY,RIL") ++ (set_attr "type" "imulsi,imulhi,imulsi,imulsi,imulsi") ++ (set_attr "cpu_facility" "*,*,*,*,z10")]) + + ; + ; mulsidi3 instruction pattern(s). + ; + + (define_insn "mulsidi3" +- [(set (match_operand:DI 0 "register_operand" "=d,d") ++ [(set (match_operand:DI 0 "register_operand" "=d,d,d") + (mult:DI (sign_extend:DI +- (match_operand:SI 1 "register_operand" "%0,0")) ++ (match_operand:SI 1 "register_operand" "%0,0,0")) + (sign_extend:DI +- (match_operand:SI 2 "nonimmediate_operand" "d,R"))))] ++ (match_operand:SI 2 "nonimmediate_operand" "d,R,T"))))] + "!TARGET_64BIT" + "@ + mr\t%0,%2 +- m\t%0,%2" +- [(set_attr "op_type" "RR,RX") +- (set_attr "type" "imulsi")]) ++ m\t%0,%2 ++ mfy\t%0,%2" ++ [(set_attr "op_type" "RR,RX,RXY") ++ (set_attr "type" "imulsi") ++ (set_attr "cpu_facility" "*,*,z10")]) + + ; + ; umulsidi3 instruction pattern(s). +@@ -4607,7 +5253,7 @@ + (mult:DI (zero_extend:DI + (match_operand:SI 1 "register_operand" "%0,0")) + (zero_extend:DI +- (match_operand:SI 2 "nonimmediate_operand" "d,m"))))] ++ (match_operand:SI 2 "nonimmediate_operand" "d,RT"))))] + "!TARGET_64BIT && TARGET_CPU_ZARCH" + "@ + mlr\t%0,%2 +@@ -4619,7 +5265,7 @@ + ; mul(tf|df|sf|td|dd)3 instruction pattern(s). + ; + +-; mxbr mdbr, meebr, mxb, mxb, meeb, mdtr, mxtr ++; mxbr, mdbr, meebr, mxb, mxb, meeb, mdtr, mxtr + (define_insn "mul<mode>3" + [(set (match_operand:FP 0 "register_operand" "=f,f") + (mult:FP (match_operand:FP 1 "nonimmediate_operand" "%<f0>,0") +@@ -4629,9 +5275,9 @@ + m<xdee><bt>r\t%0,<op1>%2 + m<xdee>b\t%0,%2" + [(set_attr "op_type" "<RRer>,RXE") +- (set_attr "type" "fmul<bfp>")]) ++ (set_attr "type" "fmul<mode>")]) + +-; maxbr, madbr, maebr, maxb, madb, maeb ++; madbr, maebr, maxb, madb, maeb + (define_insn "*fmadd<mode>" + [(set (match_operand:DSF 0 "register_operand" "=f,f") + (plus:DSF (mult:DSF (match_operand:DSF 1 "register_operand" "%f,f") +@@ -4697,7 +5343,7 @@ + (ashift:TI + (zero_extend:TI + (mod:DI (match_operand:DI 1 "register_operand" "0,0") +- (match_operand:DI 2 "general_operand" "d,m"))) ++ (match_operand:DI 2 "general_operand" "d,RT"))) + (const_int 64)) + (zero_extend:TI (div:DI (match_dup 1) (match_dup 2)))))] + "TARGET_64BIT" +@@ -4714,7 +5360,7 @@ + (zero_extend:TI + (mod:DI (match_operand:DI 1 "register_operand" "0,0") + (sign_extend:DI +- (match_operand:SI 2 "nonimmediate_operand" "d,m")))) ++ (match_operand:SI 2 "nonimmediate_operand" "d,RT")))) + (const_int 64)) + (zero_extend:TI + (div:DI (match_dup 1) (sign_extend:DI (match_dup 2))))))] +@@ -4773,7 +5419,7 @@ + (truncate:DI + (umod:TI (match_operand:TI 1 "register_operand" "0,0") + (zero_extend:TI +- (match_operand:DI 2 "nonimmediate_operand" "d,m"))))) ++ (match_operand:DI 2 "nonimmediate_operand" "d,RT"))))) + (const_int 64)) + (zero_extend:TI + (truncate:DI +@@ -4891,7 +5537,7 @@ + (truncate:SI + (umod:DI (match_operand:DI 1 "register_operand" "0,0") + (zero_extend:DI +- (match_operand:SI 2 "nonimmediate_operand" "d,m"))))) ++ (match_operand:SI 2 "nonimmediate_operand" "d,RT"))))) + (const_int 32)) + (zero_extend:DI + (truncate:SI +@@ -5089,7 +5735,7 @@ + d<xde><bt>r\t%0,<op1>%2 + d<xde>b\t%0,%2" + [(set_attr "op_type" "<RRer>,RXE") +- (set_attr "type" "fdiv<bfp>")]) ++ (set_attr "type" "fdiv<mode>")]) + + + ;; +@@ -5111,7 +5757,7 @@ + (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,m")) ++ (match_operand:DI 2 "general_operand" "d,RT")) + (const_int 0))) + (set (match_operand:DI 0 "register_operand" "=d,d") + (and:DI (match_dup 1) (match_dup 2)))] +@@ -5119,12 +5765,13 @@ + "@ + ngr\t%0,%2 + ng\t%0,%2" +- [(set_attr "op_type" "RRE,RXY")]) ++ [(set_attr "op_type" "RRE,RXY") ++ (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,m")) ++ (match_operand:DI 2 "general_operand" "d,RT")) + (const_int 0))) + (clobber (match_scratch:DI 0 "=d,d"))] + "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT +@@ -5133,16 +5780,17 @@ + "@ + ngr\t%0,%2 + ng\t%0,%2" +- [(set_attr "op_type" "RRE,RXY")]) ++ [(set_attr "op_type" "RRE,RXY") ++ (set_attr "z10prop" "z10_super_E1, z10_super_E1")]) + +-(define_insn "*anddi3_extimm" ++(define_insn "*anddi3" + [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,d,d,AQ,Q") + (and:DI (match_operand:DI 1 "nonimmediate_operand" + "%d,o,0,0,0,0,0,0,0,0,0,0") + (match_operand:DI 2 "general_operand" +- "M,M,N0HDF,N1HDF,N2HDF,N3HDF,N0SDF,N1SDF,d,m,NxQDF,Q"))) ++ "M,M,N0HDF,N1HDF,N2HDF,N3HDF,N0SDF,N1SDF,d,RT,NxQDF,Q"))) + (clobber (reg:CC CC_REGNUM))] +- "TARGET_64BIT && TARGET_EXTIMM && s390_logical_operator_ok_p (operands)" ++ "TARGET_64BIT && s390_logical_operator_ok_p (operands)" + "@ + # + # +@@ -5156,29 +5804,21 @@ + ng\t%0,%2 + # + #" +- [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RIL,RIL,RRE,RXY,SI,SS")]) ++ [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,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, ++ z10_super_E1, ++ z10_super_E1, ++ z10_super_E1, ++ z10_super_E1, ++ *, ++ *")]) + +-(define_insn "*anddi3" +- [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,AQ,Q") +- (and:DI (match_operand:DI 1 "nonimmediate_operand" +- "%d,o,0,0,0,0,0,0,0,0") +- (match_operand:DI 2 "general_operand" +- "M,M,N0HDF,N1HDF,N2HDF,N3HDF,d,m,NxQDF,Q"))) +- (clobber (reg:CC CC_REGNUM))] +- "TARGET_64BIT && !TARGET_EXTIMM && s390_logical_operator_ok_p (operands)" +- "@ +- # +- # +- nihh\t%0,%j2 +- nihl\t%0,%j2 +- nilh\t%0,%j2 +- nill\t%0,%j2 +- ngr\t%0,%2 +- ng\t%0,%2 +- # +- #" +- [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RRE,RXY,SI,SS")]) +- + (define_split + [(set (match_operand:DI 0 "s_operand" "") + (and:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" ""))) +@@ -5207,7 +5847,8 @@ + nr\t%0,%2 + n\t%0,%2 + ny\t%0,%2" +- [(set_attr "op_type" "RIL,RR,RX,RXY")]) ++ [(set_attr "op_type" "RIL,RR,RX,RXY") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,z10_super_E1")]) + + (define_insn "*andsi3_cconly" + [(set (reg CC_REGNUM) +@@ -5223,7 +5864,8 @@ + nr\t%0,%2 + n\t%0,%2 + ny\t%0,%2" +- [(set_attr "op_type" "RIL,RR,RX,RXY")]) ++ [(set_attr "op_type" "RIL,RR,RX,RXY") ++ (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") +@@ -5244,7 +5886,17 @@ + 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,RX,RXY,SI,SS") ++ (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") +@@ -5257,8 +5909,10 @@ + n\t%0,%2 + # + #" +- [(set_attr "op_type" "RR,RX,SI,SS")]) ++ [(set_attr "op_type" "RR,RX,SI,SS") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")]) + ++ + (define_split + [(set (match_operand:SI 0 "s_operand" "") + (and:SI (match_dup 0) (match_operand:SI 1 "immediate_operand" ""))) +@@ -5284,7 +5938,9 @@ + nill\t%0,%x2 + # + #" +- [(set_attr "op_type" "RR,RI,SI,SS")]) ++ [(set_attr "op_type" "RR,RI,SI,SS") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*") ++]) + + (define_insn "*andhi3_esa" + [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q") +@@ -5296,7 +5952,9 @@ + nr\t%0,%2 + # + #" +- [(set_attr "op_type" "RR,SI,SS")]) ++ [(set_attr "op_type" "RR,SI,SS") ++ (set_attr "z10prop" "z10_super_E1,*,*") ++]) + + (define_split + [(set (match_operand:HI 0 "s_operand" "") +@@ -5324,7 +5982,8 @@ + ni\t%S0,%b2 + niy\t%S0,%b2 + #" +- [(set_attr "op_type" "RR,RI,SI,SIY,SS")]) ++ [(set_attr "op_type" "RR,RI,SI,SIY,SS") ++ (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") +@@ -5336,7 +5995,8 @@ + nr\t%0,%2 + ni\t%S0,%b2 + #" +- [(set_attr "op_type" "RR,SI,SS")]) ++ [(set_attr "op_type" "RR,SI,SS") ++ (set_attr "z10prop" "z10_super_E1,z10_super,*")]) + + ; + ; Block and (NC) patterns. +@@ -5385,7 +6045,7 @@ + (clobber (reg:CC CC_REGNUM))])] + "s390_offset_p (operands[0], operands[3], operands[2]) + && s390_offset_p (operands[1], operands[4], operands[2]) +- && !s390_overlap_p (operands[0], operands[1], ++ && !s390_overlap_p (operands[0], operands[1], + INTVAL (operands[2]) + INTVAL (operands[5])) + && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256" + [(parallel +@@ -5416,7 +6076,7 @@ + (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,m")) ++ (match_operand:DI 2 "general_operand" "d,RT")) + (const_int 0))) + (set (match_operand:DI 0 "register_operand" "=d,d") + (ior:DI (match_dup 1) (match_dup 2)))] +@@ -5424,27 +6084,29 @@ + "@ + ogr\t%0,%2 + og\t%0,%2" +- [(set_attr "op_type" "RRE,RXY")]) ++ [(set_attr "op_type" "RRE,RXY") ++ (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,m")) ++ (match_operand:DI 2 "general_operand" "d,RT")) + (const_int 0))) + (clobber (match_scratch:DI 0 "=d,d"))] + "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT" + "@ + ogr\t%0,%2 + og\t%0,%2" +- [(set_attr "op_type" "RRE,RXY")]) ++ [(set_attr "op_type" "RRE,RXY") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1")]) + +-(define_insn "*iordi3_extimm" ++(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") + (match_operand:DI 2 "general_operand" +- "N0HD0,N1HD0,N2HD0,N3HD0,N0SD0,N1SD0,d,m,NxQD0,Q"))) ++ "N0HD0,N1HD0,N2HD0,N3HD0,N0SD0,N1SD0,d,RT,NxQD0,Q"))) + (clobber (reg:CC CC_REGNUM))] +- "TARGET_64BIT && TARGET_EXTIMM && s390_logical_operator_ok_p (operands)" ++ "TARGET_64BIT && s390_logical_operator_ok_p (operands)" + "@ + oihh\t%0,%i2 + oihl\t%0,%i2 +@@ -5456,26 +6118,19 @@ + og\t%0,%2 + # + #" +- [(set_attr "op_type" "RI,RI,RI,RI,RIL,RIL,RRE,RXY,SI,SS")]) ++ [(set_attr "op_type" "RI,RI,RI,RI,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, ++ z10_super_E1, ++ z10_super_E1, ++ z10_super_E1, ++ z10_super_E1, ++ *, ++ *")]) + +-(define_insn "*iordi3" +- [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,AQ,Q") +- (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0,0,0,0,0") +- (match_operand:DI 2 "general_operand" +- "N0HD0,N1HD0,N2HD0,N3HD0,d,m,NxQD0,Q"))) +- (clobber (reg:CC CC_REGNUM))] +- "TARGET_64BIT && !TARGET_EXTIMM && s390_logical_operator_ok_p (operands)" +- "@ +- oihh\t%0,%i2 +- oihl\t%0,%i2 +- oilh\t%0,%i2 +- oill\t%0,%i2 +- ogr\t%0,%2 +- og\t%0,%2 +- # +- #" +- [(set_attr "op_type" "RI,RI,RI,RI,RRE,RXY,SI,SS")]) +- + (define_split + [(set (match_operand:DI 0 "s_operand" "") + (ior:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" ""))) +@@ -5503,7 +6158,8 @@ + or\t%0,%2 + o\t%0,%2 + oy\t%0,%2" +- [(set_attr "op_type" "RIL,RR,RX,RXY")]) ++ [(set_attr "op_type" "RIL,RR,RX,RXY") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,z10_super_E1")]) + + (define_insn "*iorsi3_cconly" + [(set (reg CC_REGNUM) +@@ -5517,7 +6173,8 @@ + or\t%0,%2 + o\t%0,%2 + oy\t%0,%2" +- [(set_attr "op_type" "RIL,RR,RX,RXY")]) ++ [(set_attr "op_type" "RIL,RR,RX,RXY") ++ (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") +@@ -5534,7 +6191,15 @@ + oy\t%0,%2 + # + #" +- [(set_attr "op_type" "RI,RI,RIL,RR,RX,RXY,SI,SS")]) ++ [(set_attr "op_type" "RI,RI,RIL,RR,RX,RXY,SI,SS") ++ (set_attr "z10prop" "z10_super_E1, ++ z10_super_E1, ++ z10_super_E1, ++ z10_super_E1, ++ z10_super_E1, ++ z10_super_E1, ++ *, ++ *")]) + + (define_insn "*iorsi3_esa" + [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q") +@@ -5547,7 +6212,8 @@ + o\t%0,%2 + # + #" +- [(set_attr "op_type" "RR,RX,SI,SS")]) ++ [(set_attr "op_type" "RR,RX,SI,SS") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")]) + + (define_split + [(set (match_operand:SI 0 "s_operand" "") +@@ -5574,7 +6240,8 @@ + oill\t%0,%x2 + # + #" +- [(set_attr "op_type" "RR,RI,SI,SS")]) ++ [(set_attr "op_type" "RR,RI,SI,SS") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")]) + + (define_insn "*iorhi3_esa" + [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q") +@@ -5586,7 +6253,8 @@ + or\t%0,%2 + # + #" +- [(set_attr "op_type" "RR,SI,SS")]) ++ [(set_attr "op_type" "RR,SI,SS") ++ (set_attr "z10prop" "z10_super_E1,*,*")]) + + (define_split + [(set (match_operand:HI 0 "s_operand" "") +@@ -5614,7 +6282,8 @@ + oi\t%S0,%b2 + oiy\t%S0,%b2 + #" +- [(set_attr "op_type" "RR,RI,SI,SIY,SS")]) ++ [(set_attr "op_type" "RR,RI,SI,SIY,SS") ++ (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") +@@ -5626,7 +6295,8 @@ + or\t%0,%2 + oi\t%S0,%b2 + #" +- [(set_attr "op_type" "RR,SI,SS")]) ++ [(set_attr "op_type" "RR,SI,SS") ++ (set_attr "z10prop" "z10_super_E1,z10_super,*")]) + + ; + ; Block inclusive or (OC) patterns. +@@ -5675,7 +6345,7 @@ + (clobber (reg:CC CC_REGNUM))])] + "s390_offset_p (operands[0], operands[3], operands[2]) + && s390_offset_p (operands[1], operands[4], operands[2]) +- && !s390_overlap_p (operands[0], operands[1], ++ && !s390_overlap_p (operands[0], operands[1], + INTVAL (operands[2]) + INTVAL (operands[5])) + && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256" + [(parallel +@@ -5706,7 +6376,7 @@ + (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,m")) ++ (match_operand:DI 2 "general_operand" "d,RT")) + (const_int 0))) + (set (match_operand:DI 0 "register_operand" "=d,d") + (xor:DI (match_dup 1) (match_dup 2)))] +@@ -5714,26 +6384,28 @@ + "@ + xgr\t%0,%2 + xg\t%0,%2" +- [(set_attr "op_type" "RRE,RXY")]) ++ [(set_attr "op_type" "RRE,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,m")) ++ (match_operand:DI 2 "general_operand" "d,RT")) + (const_int 0))) + (clobber (match_scratch:DI 0 "=d,d"))] + "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT" + "@ + xgr\t%0,%2 + xg\t%0,%2" +- [(set_attr "op_type" "RRE,RXY")]) ++ [(set_attr "op_type" "RRE,RXY") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1")]) + +-(define_insn "*xordi3_extimm" ++(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,m,NxQD0,Q"))) ++ (match_operand:DI 2 "general_operand" "N0SD0,N1SD0,d,RT,NxQD0,Q"))) + (clobber (reg:CC CC_REGNUM))] +- "TARGET_64BIT && TARGET_EXTIMM && s390_logical_operator_ok_p (operands)" ++ "TARGET_64BIT && s390_logical_operator_ok_p (operands)" + "@ + xihf\t%0,%k2 + xilf\t%0,%k2 +@@ -5741,21 +6413,10 @@ + xg\t%0,%2 + # + #" +- [(set_attr "op_type" "RIL,RIL,RRE,RXY,SI,SS")]) ++ [(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,*,*")]) + +-(define_insn "*xordi3" +- [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,AQ,Q") +- (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0") +- (match_operand:DI 2 "general_operand" "d,m,NxQD0,Q"))) +- (clobber (reg:CC CC_REGNUM))] +- "TARGET_64BIT && !TARGET_EXTIMM && s390_logical_operator_ok_p (operands)" +- "@ +- xgr\t%0,%2 +- xg\t%0,%2 +- # +- #" +- [(set_attr "op_type" "RRE,RXY,SI,SS")]) +- + (define_split + [(set (match_operand:DI 0 "s_operand" "") + (xor:DI (match_dup 0) (match_operand:DI 1 "immediate_operand" ""))) +@@ -5783,7 +6444,8 @@ + xr\t%0,%2 + x\t%0,%2 + xy\t%0,%2" +- [(set_attr "op_type" "RIL,RR,RX,RXY")]) ++ [(set_attr "op_type" "RIL,RR,RX,RXY") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super_E1,z10_super_E1")]) + + (define_insn "*xorsi3_cconly" + [(set (reg CC_REGNUM) +@@ -5797,7 +6459,8 @@ + xr\t%0,%2 + x\t%0,%2 + xy\t%0,%2" +- [(set_attr "op_type" "RIL,RR,RX,RXY")]) ++ [(set_attr "op_type" "RIL,RR,RX,RXY") ++ (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") +@@ -5812,7 +6475,8 @@ + xy\t%0,%2 + # + #" +- [(set_attr "op_type" "RIL,RR,RX,RXY,SI,SS")]) ++ [(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,*,*")]) + + (define_split + [(set (match_operand:SI 0 "s_operand" "") +@@ -5839,7 +6503,8 @@ + xr\t%0,%2 + # + #" +- [(set_attr "op_type" "RIL,RR,SI,SS")]) ++ [(set_attr "op_type" "RIL,RR,SI,SS") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1,*,*")]) + + (define_split + [(set (match_operand:HI 0 "s_operand" "") +@@ -5867,8 +6532,10 @@ + xi\t%S0,%b2 + xiy\t%S0,%b2 + #" +- [(set_attr "op_type" "RIL,RR,SI,SIY,SS")]) ++ [(set_attr "op_type" "RIL,RR,SI,SIY,SS") ++ (set_attr "z10prop" "z10_super_E1,z10_super_E1,z10_super,z10_super,*")]) + ++ + ; + ; Block exclusive or (XC) patterns. + ; +@@ -5916,7 +6583,7 @@ + (clobber (reg:CC CC_REGNUM))])] + "s390_offset_p (operands[0], operands[3], operands[2]) + && s390_offset_p (operands[1], operands[4], operands[2]) +- && !s390_overlap_p (operands[0], operands[1], ++ && !s390_overlap_p (operands[0], operands[1], + INTVAL (operands[2]) + INTVAL (operands[5])) + && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256" + [(parallel +@@ -5988,7 +6655,7 @@ + "TARGET_64BIT && s390_match_ccmode (insn, CCAmode)" + "lcgfr\t%0,%1" + [(set_attr "op_type" "RRE")]) +- ++ + (define_insn "*negdi2_sign" + [(set (match_operand:DI 0 "register_operand" "=d") + (neg:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "d")))) +@@ -6006,7 +6673,8 @@ + (neg:GPR (match_dup 1)))] + "s390_match_ccmode (insn, CCAmode)" + "lc<g>r\t%0,%1" +- [(set_attr "op_type" "RR<E>")]) ++ [(set_attr "op_type" "RR<E>") ++ (set_attr "z10prop" "z10_super_c_E1")]) + + ; lcr, lcgr + (define_insn "*neg<mode>2_cconly" +@@ -6016,7 +6684,8 @@ + (clobber (match_scratch:GPR 0 "=d"))] + "s390_match_ccmode (insn, CCAmode)" + "lc<g>r\t%0,%1" +- [(set_attr "op_type" "RR<E>")]) ++ [(set_attr "op_type" "RR<E>") ++ (set_attr "z10prop" "z10_super_c_E1")]) + + ; lcr, lcgr + (define_insn "*neg<mode>2" +@@ -6025,7 +6694,8 @@ + (clobber (reg:CC CC_REGNUM))] + "" + "lc<g>r\t%0,%1" +- [(set_attr "op_type" "RR<E>")]) ++ [(set_attr "op_type" "RR<E>") ++ (set_attr "z10prop" "z10_super_c_E1")]) + + (define_insn_and_split "*negdi2_31" + [(set (match_operand:DI 0 "register_operand" "=d") +@@ -6094,10 +6764,10 @@ + (define_insn "*neg<mode>2_nocc" + [(set (match_operand:FP 0 "register_operand" "=f") + (neg:FP (match_operand:FP 1 "register_operand" "<fT0>")))] +- "TARGET_HARD_FLOAT && TARGET_DFP" ++ "TARGET_DFP" + "lcdfr\t%0,%1" + [(set_attr "op_type" "RRE") +- (set_attr "type" "fsimp<bfp>")]) ++ (set_attr "type" "fsimp<mode>")]) + + ; lcxbr, lcdbr, lcebr + (define_insn "*neg<mode>2" +@@ -6147,9 +6817,10 @@ + (abs:GPR (match_dup 1)))] + "s390_match_ccmode (insn, CCAmode)" + "lp<g>r\t%0,%1" +- [(set_attr "op_type" "RR<E>")]) ++ [(set_attr "op_type" "RR<E>") ++ (set_attr "z10prop" "z10_c")]) + +-; lpr, lpgr ++; lpr, lpgr + (define_insn "*abs<mode>2_cconly" + [(set (reg CC_REGNUM) + (compare (abs:GPR (match_operand:GPR 1 "register_operand" "d")) +@@ -6157,7 +6828,8 @@ + (clobber (match_scratch:GPR 0 "=d"))] + "s390_match_ccmode (insn, CCAmode)" + "lp<g>r\t%0,%1" +- [(set_attr "op_type" "RR<E>")]) ++ [(set_attr "op_type" "RR<E>") ++ (set_attr "z10prop" "z10_c")]) + + ; lpr, lpgr + (define_insn "abs<mode>2" +@@ -6166,7 +6838,8 @@ + (clobber (reg:CC CC_REGNUM))] + "" + "lp<g>r\t%0,%1" +- [(set_attr "op_type" "RR<E>")]) ++ [(set_attr "op_type" "RR<E>") ++ (set_attr "z10prop" "z10_c")]) + + ; + ; abs(df|sf)2 instruction pattern(s). +@@ -6207,10 +6880,10 @@ + (define_insn "*abs<mode>2_nocc" + [(set (match_operand:FP 0 "register_operand" "=f") + (abs:FP (match_operand:FP 1 "register_operand" "<fT0>")))] +- "TARGET_HARD_FLOAT && TARGET_DFP" ++ "TARGET_DFP" + "lpdfr\t%0,%1" + [(set_attr "op_type" "RRE") +- (set_attr "type" "fsimp<bfp>")]) ++ (set_attr "type" "fsimp<mode>")]) + + ; lpxbr, lpdbr, lpebr + (define_insn "*abs<mode>2" +@@ -6242,7 +6915,7 @@ + "TARGET_64BIT && s390_match_ccmode (insn, CCAmode)" + "lngfr\t%0,%1" + [(set_attr "op_type" "RRE")]) +- ++ + (define_insn "*negabsdi2_sign" + [(set (match_operand:DI 0 "register_operand" "=d") + (neg:DI (abs:DI (sign_extend:DI +@@ -6261,7 +6934,8 @@ + (neg:GPR (abs:GPR (match_dup 1))))] + "s390_match_ccmode (insn, CCAmode)" + "ln<g>r\t%0,%1" +- [(set_attr "op_type" "RR<E>")]) ++ [(set_attr "op_type" "RR<E>") ++ (set_attr "z10prop" "z10_c")]) + + ; lnr, lngr + (define_insn "*negabs<mode>2_cconly" +@@ -6271,7 +6945,8 @@ + (clobber (match_scratch:GPR 0 "=d"))] + "s390_match_ccmode (insn, CCAmode)" + "ln<g>r\t%0,%1" +- [(set_attr "op_type" "RR<E>")]) ++ [(set_attr "op_type" "RR<E>") ++ (set_attr "z10prop" "z10_c")]) + + ; lnr, lngr + (define_insn "*negabs<mode>2" +@@ -6280,7 +6955,8 @@ + (clobber (reg:CC CC_REGNUM))] + "" + "ln<g>r\t%0,%1" +- [(set_attr "op_type" "RR<E>")]) ++ [(set_attr "op_type" "RR<E>") ++ (set_attr "z10prop" "z10_c")]) + + ; + ; Floating point +@@ -6313,10 +6989,10 @@ + (define_insn "*negabs<mode>2_nocc" + [(set (match_operand:FP 0 "register_operand" "=f") + (neg:FP (abs:FP (match_operand:BFP 1 "register_operand" "<fT0>"))))] +- "TARGET_HARD_FLOAT && TARGET_DFP" ++ "TARGET_DFP" + "lndfr\t%0,%1" + [(set_attr "op_type" "RRE") +- (set_attr "type" "fsimp<bfp>")]) ++ (set_attr "type" "fsimp<mode>")]) + + ; lnxbr, lndbr, lnebr + (define_insn "*negabs<mode>2" +@@ -6336,12 +7012,12 @@ + (define_insn "copysign<mode>3" + [(set (match_operand:FP 0 "register_operand" "=f") + (unspec:FP [(match_operand:FP 1 "register_operand" "<fT0>") +- (match_operand:FP 2 "register_operand" "f")] ++ (match_operand:FP 2 "register_operand" "f")] + UNSPEC_COPYSIGN))] +- "TARGET_HARD_FLOAT && TARGET_DFP" ++ "TARGET_DFP" + "cpsdr\t%0,%2,%1" + [(set_attr "op_type" "RRF") +- (set_attr "type" "fsimp<bfp>")]) ++ (set_attr "type" "fsimp<mode>")]) + + ;; + ;;- Square root instructions. +@@ -6351,7 +7027,7 @@ + ; sqrt(df|sf)2 instruction pattern(s). + ; + +-; sqxbr, sqdbr, sqebr, sqxb, sqdb, sqeb ++; sqxbr, sqdbr, sqebr, sqdb, sqeb + (define_insn "sqrt<mode>2" + [(set (match_operand:BFP 0 "register_operand" "=f,f") + (sqrt:BFP (match_operand:BFP 1 "general_operand" "f,<Rf>")))] +@@ -6398,7 +7074,7 @@ + + emit_insn (gen_clztidi2 (wide_reg, operands[1], msb)); + +- insn = emit_move_insn (operands[0], gen_highpart (DImode, wide_reg)); ++ insn = emit_move_insn (operands[0], gen_highpart (DImode, wide_reg)); + set_unique_reg_note (insn, REG_EQUAL, clz_equal); + + DONE; +@@ -6407,16 +7083,16 @@ + (define_insn "clztidi2" + [(set (match_operand:TI 0 "register_operand" "=d") + (ior:TI +- (ashift:TI +- (zero_extend:TI ++ (ashift:TI ++ (zero_extend:TI + (xor:DI (match_operand:DI 1 "register_operand" "d") + (lshiftrt (match_operand:DI 2 "const_int_operand" "") + (subreg:SI (clz:DI (match_dup 1)) 4)))) +- ++ + (const_int 64)) + (zero_extend:TI (clz:DI (match_dup 1))))) + (clobber (reg:CC CC_REGNUM))] +- "(unsigned HOST_WIDE_INT) INTVAL (operands[2]) ++ "(unsigned HOST_WIDE_INT) INTVAL (operands[2]) + == (unsigned HOST_WIDE_INT) 1 << 63 + && TARGET_EXTIMM && TARGET_64BIT" + "flogr\t%0,%1" +@@ -6439,7 +7115,8 @@ + "TARGET_CPU_ZARCH" + "rll<g>\t%0,%1,%Y2" + [(set_attr "op_type" "RSE") +- (set_attr "atype" "reg")]) ++ (set_attr "atype" "reg") ++ (set_attr "z10prop" "z10_super_E1")]) + + ; rll, rllg + (define_insn "*rotl<mode>3_and" +@@ -6450,7 +7127,8 @@ + "TARGET_CPU_ZARCH && (INTVAL (operands[3]) & 63) == 63" + "rll<g>\t%0,%1,%Y2" + [(set_attr "op_type" "RSE") +- (set_attr "atype" "reg")]) ++ (set_attr "atype" "reg") ++ (set_attr "z10prop" "z10_super_E1")]) + + + ;; +@@ -6486,7 +7164,8 @@ + "" + "s<lr>l<g>\t%0,<1>%Y2" + [(set_attr "op_type" "RS<E>") +- (set_attr "atype" "reg")]) ++ (set_attr "atype" "reg") ++ (set_attr "z10prop" "z10_super_E1")]) + + ; sldl, srdl + (define_insn "*<shift>di3_31_and" +@@ -6508,7 +7187,8 @@ + "(INTVAL (operands[3]) & 63) == 63" + "s<lr>l<g>\t%0,<1>%Y2" + [(set_attr "op_type" "RS<E>") +- (set_attr "atype" "reg")]) ++ (set_attr "atype" "reg") ++ (set_attr "z10prop" "z10_super_E1")]) + + ; + ; ashr(di|si)3 instruction pattern(s). +@@ -6567,7 +7247,8 @@ + "s390_match_ccmode(insn, CCSmode)" + "sra<g>\t%0,<1>%Y2" + [(set_attr "op_type" "RS<E>") +- (set_attr "atype" "reg")]) ++ (set_attr "atype" "reg") ++ (set_attr "z10prop" "z10_super_E1")]) + + ; sra, srag + (define_insn "*ashr<mode>3_cconly" +@@ -6579,7 +7260,8 @@ + "s390_match_ccmode(insn, CCSmode)" + "sra<g>\t%0,<1>%Y2" + [(set_attr "op_type" "RS<E>") +- (set_attr "atype" "reg")]) ++ (set_attr "atype" "reg") ++ (set_attr "z10prop" "z10_super_E1")]) + + ; sra, srag + (define_insn "*ashr<mode>3" +@@ -6590,7 +7272,8 @@ + "" + "sra<g>\t%0,<1>%Y2" + [(set_attr "op_type" "RS<E>") +- (set_attr "atype" "reg")]) ++ (set_attr "atype" "reg") ++ (set_attr "z10prop" "z10_super_E1")]) + + + ; shift pattern with implicit ANDs +@@ -6645,7 +7328,8 @@ + "s390_match_ccmode(insn, CCSmode) && (INTVAL (operands[3]) & 63) == 63" + "sra<g>\t%0,<1>%Y2" + [(set_attr "op_type" "RS<E>") +- (set_attr "atype" "reg")]) ++ (set_attr "atype" "reg") ++ (set_attr "z10prop" "z10_super_E1")]) + + ; sra, srag + (define_insn "*ashr<mode>3_cconly_and" +@@ -6658,7 +7342,8 @@ + "s390_match_ccmode(insn, CCSmode) && (INTVAL (operands[3]) & 63) == 63" + "sra<g>\t%0,<1>%Y2" + [(set_attr "op_type" "RS<E>") +- (set_attr "atype" "reg")]) ++ (set_attr "atype" "reg") ++ (set_attr "z10prop" "z10_super_E1")]) + + ; sra, srag + (define_insn "*ashr<mode>3_and" +@@ -6670,7 +7355,8 @@ + "(INTVAL (operands[3]) & 63) == 63" + "sra<g>\t%0,<1>%Y2" + [(set_attr "op_type" "RS<E>") +- (set_attr "atype" "reg")]) ++ (set_attr "atype" "reg") ++ (set_attr "z10prop" "z10_super_E1")]) + + + ;; +@@ -6830,7 +7516,7 @@ + "" + { + if (operands[1] != const0_rtx) FAIL; +- operands[0] = s390_emit_compare (GET_CODE (operands[0]), ++ operands[0] = s390_emit_compare (GET_CODE (operands[0]), + s390_compare_op0, s390_compare_op1); + }) + +@@ -6842,6 +7528,34 @@ + [(set_attr "op_type" "RI") + (set_attr "type" "branch")]) + ++; crt, cgrt, cit, cgit ++(define_insn "*cmp_and_trap_signed_int<mode>" ++ [(trap_if (match_operator 0 "s390_signed_integer_comparison" ++ [(match_operand:GPR 1 "register_operand" "d,d") ++ (match_operand:GPR 2 "nonmemory_operand" "d,K")]) ++ (const_int 0))] ++ "TARGET_Z10" ++ "@ ++ c<g>rt%C0\t%1,%2 ++ c<g>it%C0\t%1,%h2" ++ [(set_attr "op_type" "RRF,RIE") ++ (set_attr "type" "branch") ++ (set_attr "z10prop" "z10_c,*")]) ++ ++; clrt, clgrt, clfit, clgit ++(define_insn "*cmp_and_trap_unsigned_int<mode>" ++ [(trap_if (match_operator 0 "s390_unsigned_integer_comparison" ++ [(match_operand:GPR 1 "register_operand" "d,d") ++ (match_operand:GPR 2 "nonmemory_operand" "d,D")]) ++ (const_int 0))] ++ "TARGET_Z10" ++ "@ ++ cl<g>rt%C0\t%1,%2 ++ cl<gf>it%C0\t%1,%x2" ++ [(set_attr "op_type" "RRF,RIE") ++ (set_attr "type" "branch") ++ (set_attr "z10prop" "z10_c,*")]) ++ + ;; + ;;- Loop instructions. + ;; +@@ -6902,6 +7616,9 @@ + (pc)))] + "" + [(set_attr "op_type" "RI") ++ ; Strictly speaking, the z10 properties are valid for brct only, however, it does not ++ ; hurt us in the (rare) case of ahi. ++ (set_attr "z10prop" "z10_super") + (set_attr "type" "branch") + (set (attr "length") + (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) +@@ -6941,6 +7658,9 @@ + (pc)))] + "" + [(set_attr "op_type" "RI") ++ ; Strictly speaking, the z10 properties are valid for brct only, however, it does not ++ ; hurt us in the (rare) case of ahi. ++ (set_attr "z10prop" "z10_super") + (set_attr "type" "branch") + (set (attr "length") + (if_then_else (eq (symbol_ref "flag_pic") (const_int 0)) +@@ -7007,6 +7727,9 @@ + (pc)))] + "" + [(set_attr "op_type" "RI") ++ ; Strictly speaking, the z10 properties are valid for brct only, however, it does not ++ ; hurt us in the (rare) case of ahi. ++ (set_attr "z10prop" "z10_super") + (set_attr "type" "branch") + (set (attr "length") + (if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000)) +@@ -7073,7 +7796,8 @@ + (if_then_else (match_operand 0 "register_operand" "") + (const_string "RR") (const_string "RX"))) + (set_attr "type" "branch") +- (set_attr "atype" "agen")]) ++ (set_attr "atype" "agen") ++ (set_attr "z10prop" "z10_super")]) + + ; + ; casesi instruction pattern(s). +@@ -7411,12 +8135,13 @@ + + (define_insn "*tls_load_64" + [(set (match_operand:DI 0 "register_operand" "=d") +- (unspec:DI [(match_operand:DI 1 "memory_operand" "m") ++ (unspec:DI [(match_operand:DI 1 "memory_operand" "RT") + (match_operand:DI 2 "" "")] + UNSPEC_TLS_LOAD))] + "TARGET_64BIT" + "lg\t%0,%1%J2" +- [(set_attr "op_type" "RXE")]) ++ [(set_attr "op_type" "RXE") ++ (set_attr "z10prop" "z10_fwd_A3")]) + + (define_insn "*tls_load_31" + [(set (match_operand:SI 0 "register_operand" "=d,d") +@@ -7427,7 +8152,8 @@ + "@ + l\t%0,%1%J2 + ly\t%0,%1%J2" +- [(set_attr "op_type" "RX,RXY")]) ++ [(set_attr "op_type" "RX,RXY") ++ (set_attr "z10prop" "z10_fwd_A3,z10_fwd_A3")]) + + (define_insn "*bras_tls" + [(set (match_operand 0 "" "") +@@ -7497,6 +8223,8 @@ + "" + "bcr\t15,0" + [(set_attr "op_type" "RR")]) ++; Although bcr is superscalar on Z10, this variant will never become part of ++; an execution group. + + ; + ; compare and swap patterns. +@@ -7529,7 +8257,7 @@ + (set (reg:CCZ1 CC_REGNUM) + (compare:CCZ1 (match_dup 1) (match_dup 2)))])] + "" +- "s390_expand_cs_hqi (<MODE>mode, operands[0], operands[1], ++ "s390_expand_cs_hqi (<MODE>mode, operands[0], operands[1], + operands[2], operands[3]); DONE;") + + (define_expand "sync_compare_and_swap_cc<mode>" +@@ -7582,7 +8310,7 @@ + UNSPECV_CAS)) + (set (reg:CCZ1 CC_REGNUM) + (compare:CCZ1 (match_dup 1) (match_dup 2)))] +- "" ++ "" + "cs<g>\t%0,%3,%S1" + [(set_attr "op_type" "RS<E>") + (set_attr "type" "sem")]) +@@ -7597,7 +8325,7 @@ + (match_operand:HQI 1 "memory_operand") + (match_operand:HQI 2 "general_operand")] + "" +- "s390_expand_atomic (<MODE>mode, SET, operands[0], operands[1], ++ "s390_expand_atomic (<MODE>mode, SET, operands[0], operands[1], + operands[2], false); DONE;") + + (define_expand "sync_<atomic><mode>" +@@ -7605,7 +8333,7 @@ + (ATOMIC:HQI (match_dup 0) + (match_operand:HQI 1 "general_operand")))] + "" +- "s390_expand_atomic (<MODE>mode, <CODE>, NULL_RTX, operands[0], ++ "s390_expand_atomic (<MODE>mode, <CODE>, NULL_RTX, operands[0], + operands[1], false); DONE;") + + (define_expand "sync_old_<atomic><mode>" +@@ -7615,16 +8343,16 @@ + (ATOMIC:HQI (match_dup 1) + (match_operand:HQI 2 "general_operand")))] + "" +- "s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1], ++ "s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1], + operands[2], false); DONE;") + + (define_expand "sync_new_<atomic><mode>" + [(set (match_operand:HQI 0 "register_operand") + (ATOMIC:HQI (match_operand:HQI 1 "memory_operand") +- (match_operand:HQI 2 "general_operand"))) ++ (match_operand:HQI 2 "general_operand"))) + (set (match_dup 1) (ATOMIC:HQI (match_dup 1) (match_dup 2)))] + "" +- "s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1], ++ "s390_expand_atomic (<MODE>mode, <CODE>, operands[0], operands[1], + operands[2], true); DONE;") + + ;; +@@ -7736,7 +8464,7 @@ + + if (TARGET_BACKCHAIN) + temp = force_reg (Pmode, operand_subword (operands[1], 0, 0, mode)); +- ++ + emit_move_insn (base, operand_subword (operands[1], 2, 0, mode)); + emit_move_insn (operands[0], operand_subword (operands[1], 1, 0, mode)); + +@@ -7824,7 +8552,8 @@ + "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode" + "larl\t%0,%1" + [(set_attr "op_type" "RIL") +- (set_attr "type" "larl")]) ++ (set_attr "type" "larl") ++ (set_attr "z10prop" "z10_super_A1")]) + + (define_insn "main_pool" + [(set (match_operand 0 "register_operand" "=a") +@@ -7833,7 +8562,7 @@ + { + gcc_unreachable (); + } +- [(set (attr "type") ++ [(set (attr "type") + (if_then_else (ne (symbol_ref "TARGET_CPU_ZARCH") (const_int 0)) + (const_string "larl") (const_string "la")))]) + +@@ -7851,7 +8580,8 @@ + "TARGET_CPU_ZARCH && GET_MODE (operands[0]) == Pmode" + "larl\t%0,%1" + [(set_attr "op_type" "RIL") +- (set_attr "type" "larl")]) ++ (set_attr "type" "larl") ++ (set_attr "z10prop" "z10_super_A1")]) + + (define_insn "pool" + [(unspec_volatile [(match_operand 0 "const_int_operand" "n")] UNSPECV_POOL)] +@@ -7988,3 +8718,31 @@ + "" + "" + [(set_attr "length" "0")]) ++ ++ ++; ++; Data prefetch patterns ++; ++ ++(define_insn "prefetch" ++ [(prefetch (match_operand 0 "address_operand" "UW,X") ++ (match_operand:SI 1 "const_int_operand" "n,n") ++ (match_operand:SI 2 "const_int_operand" "n,n"))] ++ "TARGET_Z10" ++{ ++ if (larl_operand (operands[0], Pmode)) ++ return INTVAL (operands[1]) == 1 ? "pfdrl\t2,%a0" : "pfdrl\t1,%a0"; ++ ++ if (s390_mem_constraint ("W", operands[0]) ++ || s390_mem_constraint ("U", operands[0])) ++ return INTVAL (operands[1]) == 1 ? "pfd\t2,%a0" : "pfd\t1,%a0"; ++ ++ /* This point might be reached if op0 is a larl operand with an ++ uneven addend. In this case we simply omit issuing a prefetch ++ instruction. */ ++ ++ return ""; ++} ++ [(set_attr "type" "load,larl") ++ (set_attr "op_type" "RXY,RIL") ++ (set_attr "z10prop" "z10_super")]) +Index: gcc/config/s390/2097.md +=================================================================== +--- gcc/config/s390/2097.md (revision 0) ++++ gcc/config/s390/2097.md (revision 0) +@@ -0,0 +1,764 @@ ++;; Scheduling description for z10 (cpu 2097). ++;; Copyright (C) 2008 Free Software Foundation, Inc. ++;; Contributed by Wolfgang Gellerich (gellerich@de.ibm.com). ++ ++ ++; General naming conventions used in this file: ++; - The two pipelines are called S and T, respectively. ++; - A name ending "_S" or "_T" indicates that something happens in ++; (or belongs to) this pipeline. ++; - A name ending "_ANY" indicates that something happens in (or belongs ++; to) either of the two pipelines. ++; - A name ending "_BOTH" indicates that something happens in (or belongs ++; to) both pipelines. ++ ++ ++;; Automaton and components. ++ ++(define_automaton "z10_cpu") ++ ++(define_cpu_unit "z10_e1_S, z10_e1_T" "z10_cpu") ++(define_reservation "z10_e1_ANY" "(z10_e1_S | z10_e1_T)") ++(define_reservation "z10_e1_BOTH" "(z10_e1_S + z10_e1_T)") ++ ++ ++; Both pipelines can execute a branch instruction, and branch ++; instructions can be grouped with all other groupable instructions ++; but not with a second branch instruction. ++ ++(define_cpu_unit "z10_branch_ANY" "z10_cpu") ++ ++(define_insn_reservation "z10_branch" 4 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "branch")) ++ "z10_branch_ANY + z10_e1_ANY, z10_Gate_ANY") ++ ++ ++; Z10 operand and result forwarding. ++ ++; Instructions marked with the attributes as z10_fwd or z10_fr can ++; forward a value they load from one of their operants into a register ++; if the instruction in the second pipeline reads the same register. ++; The second operation must be superscalar. Instructions marked as ++; z10_rec or z10_fr can receive a value they read from a register is ++; this register gets updated by an instruction in the first pipeline. ++; The first instruction must be superscalar. ++ ++ ++; Forwarding from z10_fwd and z10_fr to z10_super. ++ ++(define_bypass 0 "z10_la_fwd, z10_la_fwd_A1, z10_larl_fwd, z10_larl_fwd_A3, \ ++ z10_load_fwd, z10_load_fwd_A3, \ ++ z10_other_fwd, z10_other_fwd_A1, z10_other_fwd_A3, \ ++ z10_other_fr, z10_other_fr_A3, z10_other_fr_E1, \ ++ z10_other_fwd_E1, z10_lr_fr, z10_lr_fr_E1, \ ++ z10_int_fwd, z10_int_fwd_A1, z10_int_fwd_A3, \ ++ z10_int_fwd_E1, z10_int_fr, z10_int_fr_E1, \ ++ z10_int_fr_A3" ++ "z10_other_super, z10_other_super_c_E1, z10_other_super_E1, \ ++ z10_int_super, z10_int_super_E1, \ ++ z10_lr, z10_store_super") ++ ++ ++; Forwarding from z10_super to frz10_ and z10_rec. ++ ++(define_bypass 0 "z10_other_super, z10_other_super_E1, z10_other_super_c_E1, \ ++ z10_int_super, z10_int_super_E1, \ ++ z10_larl_super_E1, z10_larl_super, \ ++ z10_store_super" ++ "z10_int_fr, z10_int_fr_E1, z10_int_fr_A3, \ ++ z10_other_fr, z10_other_fr_A3, z10_lr_fr, z10_lr_fr_E1, \ ++ z10_other_fr_E1, z10_store_rec") ++ ++ ++; Forwarding from z10_fwd and z10_fr to z10_rec and z10_fr. ++ ++(define_bypass 0 "z10_la_fwd, z10_la_fwd_A1, z10_larl_fwd, z10_larl_fwd_A3, \ ++ z10_load_fwd, z10_load_fwd_A3, \ ++ z10_other_fwd, z10_other_fwd_A1, z10_other_fwd_A3, \ ++ z10_other_fr, z10_other_fr_A3, z10_other_fr_E1, \ ++ z10_other_fwd_E1, \ ++ z10_lr_fr, z10_lr_fr_E1, \ ++ z10_int_fwd, z10_int_fwd_A1, z10_int_fwd_A3, \ ++ z10_int_fwd_E1, z10_int_fr, z10_int_fr_E1, \ ++ z10_int_fr_A3" ++ "z10_int_fr, z10_int_fr_E1, z10_int_fr_A3, \ ++ z10_other_fr, z10_other_fr_A3, z10_lr_fr, z10_lr_fr_E1, \ ++ z10_other_fr_E1, z10_store_rec") ++ ++ ++; ++; Simple insns ++; ++ ++; Here is the cycle diagram for FXU-executed instructions: ++; ... A1 A2 A3 E1 P1 P2 P3 R0 ... ++; ^ ^ ^ ++; | | updated GPR is available ++; | write to GPR ++; instruction reads GPR during this cycle ++ ++ ++; Variants of z10_int follow. ++ ++(define_insn_reservation "z10_int" 6 ++ (and (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "integer")) ++ (and (eq_attr "atype" "reg") ++ (and (and (eq_attr "z10prop" "!z10_super") ++ (eq_attr "z10prop" "!z10_super_c")) ++ (and (and (and (and (eq_attr "z10prop" "!z10_super_E1") ++ (eq_attr "z10prop" "!z10_super_c_E1")) ++ (eq_attr "z10prop" "!z10_fwd")) ++ (and (eq_attr "z10prop" "!z10_fwd_A1") ++ (eq_attr "z10prop" "!z10_fwd_A3"))) ++ (and (and (eq_attr "z10prop" "!z10_fwd_E1") ++ (eq_attr "z10prop" "!z10_fr")) ++ (and (eq_attr "z10prop" "!z10_fr_E1") ++ (eq_attr "z10prop" "!z10_fr_A3"))))))) ++ "z10_e1_ANY, z10_Gate_ANY") ++ ++(define_insn_reservation "z10_int_super" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "integer") ++ (and (eq_attr "atype" "reg") ++ (ior (eq_attr "z10prop" "z10_super") ++ (eq_attr "z10prop" "z10_super_c"))))) ++ "z10_e1_ANY, z10_Gate_ANY") ++ ++(define_insn_reservation "z10_int_super_E1" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "integer") ++ (and (eq_attr "atype" "reg") ++ (ior (eq_attr "z10prop" "z10_super_E1") ++ (eq_attr "z10prop" "z10_super_c_E1"))))) ++ "z10_e1_ANY, z10_Gate_ANY") ++ ++(define_insn_reservation "z10_int_fwd" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "integer") ++ (and (eq_attr "atype" "reg") ++ (eq_attr "z10prop" "z10_fwd")))) ++ "z10_e1_ANY, z10_Gate_ANY") ++ ++(define_insn_reservation "z10_int_fwd_A1" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "integer") ++ (and (eq_attr "atype" "reg") ++ (eq_attr "z10prop" "z10_fwd_A1")))) ++ "z10_e1_ANY, z10_Gate_ANY") ++ ++(define_insn_reservation "z10_int_fwd_A3" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "integer") ++ (and (eq_attr "atype" "reg") ++ (eq_attr "z10prop" "z10_fwd_A3")))) ++ "z10_e1_ANY, z10_Gate_ANY") ++ ++(define_insn_reservation "z10_int_fwd_E1" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "integer") ++ (and (eq_attr "atype" "reg") ++ (eq_attr "z10prop" "z10_fwd_E1")))) ++ "z10_e1_ANY, z10_Gate_ANY") ++ ++(define_insn_reservation "z10_int_fr" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "integer") ++ (and (eq_attr "atype" "reg") ++ (eq_attr "z10prop" "z10_fr")))) ++ "z10_e1_ANY, z10_Gate_ANY") ++ ++(define_insn_reservation "z10_int_fr_E1" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "integer") ++ (and (eq_attr "atype" "reg") ++ (eq_attr "z10prop" "z10_fr_E1")))) ++ "z10_e1_ANY, z10_Gate_ANY") ++ ++(define_insn_reservation "z10_int_fr_A3" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "integer") ++ (and (eq_attr "atype" "reg") ++ (eq_attr "z10prop" "z10_fr_A3")))) ++ "z10_e1_ANY, z10_Gate_ANY") ++ ++; END of z10_int variants ++ ++ ++(define_insn_reservation "z10_agen" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "integer") ++ (eq_attr "atype" "agen"))) ++ "z10_e1_ANY, z10_Gate_ANY") ++ ++ ++(define_insn_reservation "z10_lr" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "lr") ++ (and (eq_attr "z10prop" "!z10_fr") ++ (eq_attr "z10prop" "!z10_fr_E1")))) ++ "z10_e1_ANY, z10_Gate_ANY") ++ ++(define_insn_reservation "z10_lr_fr" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "lr") ++ (eq_attr "z10prop" "z10_fr"))) ++ "z10_e1_ANY, z10_Gate_ANY") ++; "z10_e1_ANY") ++ ++(define_insn_reservation "z10_lr_fr_E1" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "lr") ++ (eq_attr "z10prop" "z10_fr_E1"))) ++ "z10_e1_ANY, z10_Gate_ANY") ++; "z10_e1_ANY") ++ ++ ++(define_insn_reservation "z10_la" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "la") ++ (and (eq_attr "z10prop" "!z10_fwd") ++ (eq_attr "z10prop" "!z10_fwd_A1")))) ++ "z10_e1_ANY, z10_Gate_ANY") ++ ++(define_insn_reservation "z10_la_fwd" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "la") ++ (eq_attr "z10prop" "z10_fwd"))) ++ "z10_e1_ANY, z10_Gate_ANY") ++; "z10_e1_ANY") ++ ++(define_insn_reservation "z10_la_fwd_A1" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "la") ++ (eq_attr "z10prop" "z10_fwd_A1"))) ++ "z10_e1_ANY, z10_Gate_ANY") ++; "z10_e1_ANY") ++ ++ ++; larl-type instructions ++ ++(define_insn_reservation "z10_larl" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "larl") ++ (and (eq_attr "z10prop" "!z10_super_A1") ++ (and (eq_attr "z10prop" "!z10_fwd") ++ (and (eq_attr "z10prop" "!z10_fwd_A3") ++ (and (eq_attr "z10prop" "!z10_super") ++ (eq_attr "z10prop" "!z10_super_c")) ++ (and (eq_attr "z10prop" "!z10_super_E1") ++ (eq_attr "z10prop" "!z10_super_c_E1"))))))) ++ "z10_e1_ANY, z10_Gate_ANY") ++ ++(define_insn_reservation "z10_larl_super" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "larl") ++ (and (eq_attr "z10prop" "z10_super") ++ (eq_attr "z10prop" "z10_super_c")))) ++ "z10_e1_ANY, z10_Gate_ANY") ++ ++(define_insn_reservation "z10_larl_fwd" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "larl") ++ (eq_attr "z10prop" "z10_fwd"))) ++ "z10_e1_ANY, z10_Gate_ANY") ++ ++(define_insn_reservation "z10_larl_fwd_A3" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "larl") ++ (eq_attr "z10prop" "z10_fwd_A3"))) ++ "z10_e1_ANY, z10_Gate_ANY") ++ ++ ++(define_insn_reservation "z10_larl_A1" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "larl") ++ (eq_attr "z10prop" "z10_super_A1"))) ++ "z10_e1_ANY, z10_Gate_ANY") ++; "z10_e1_ANY") ++ ++(define_insn_reservation "z10_larl_super_E1" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "larl") ++ (ior (eq_attr "z10prop" "z10_super_E1") ++ (eq_attr "z10prop" "z10_super_c_E1")))) ++ "z10_e1_ANY, z10_Gate_ANY") ++; "z10_e1_ANY") ++ ++ ++(define_insn_reservation "z10_load" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "load") ++ (and (eq_attr "z10prop" "!z10_fwd") ++ (eq_attr "z10prop" "!z10_fwd_A3")))) ++ "z10_e1_ANY, z10_Gate_ANY") ++ ++(define_insn_reservation "z10_load_fwd" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "load") ++ (eq_attr "z10prop" "z10_fwd"))) ++ "z10_e1_ANY, z10_Gate_ANY") ++; "z10_e1_ANY") ++ ++(define_insn_reservation "z10_load_fwd_A3" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "load") ++ (eq_attr "z10prop" "z10_fwd_A3"))) ++ "z10_e1_ANY, z10_Gate_ANY") ++; "z10_e1_ANY") ++ ++(define_insn_reservation "z10_store" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "store") ++ (and (eq_attr "z10prop" "!z10_rec") ++ (and (eq_attr "z10prop" "!z10_super") ++ (eq_attr "z10prop" "!z10_super_c"))))) ++ "z10_e1_ANY, z10_Gate_ANY") ++ ++(define_insn_reservation "z10_store_super" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "store") ++ (ior (eq_attr "z10prop" "z10_super") ++ (eq_attr "z10prop" "z10_super_c")))) ++ "z10_e1_ANY, z10_Gate_ANY") ++ ++(define_insn_reservation "z10_store_rec" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "store") ++ (eq_attr "z10prop" "z10_rec"))) ++ "z10_e1_ANY, z10_Gate_ANY") ++ ++; The default_latency is chosen to drain off the pipeline. ++(define_insn_reservation "z10_call" 14 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "jsr")) ++ "z10_e1_BOTH*4, z10_Gate_BOTH") ++ ++; The default latency is for worst case. CS and CSG take one ++; cycle only (i.e. latency would be 6). ++(define_insn_reservation "z10_sem" 9 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "sem")) ++ "z10_e1_BOTH*5, z10_Gate_ANY") ++ ++(define_insn_reservation "z10_cs" 6 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "cs")) ++ "z10_e1_BOTH, z10_Gate_BOTH") ++ ++(define_insn_reservation "z10_vs" 6 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "vs")) ++ "z10_e1_BOTH*4, z10_Gate_BOTH") ++ ++; Load and store multiple. Actual number of cycles ++; in unknown at compile.time. ++(define_insn_reservation "z10_stm" 10 ++ (and (eq_attr "cpu" "z10") ++ (ior (eq_attr "type" "stm") ++ (eq_attr "type" "lm"))) ++ "z10_e1_BOTH*4, z10_Gate_BOTH") ++ ++ ++; Subsets of z10_other follow. ++ ++(define_insn_reservation "z10_other" 6 ++ (and (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "other")) ++ (and (and (eq_attr "z10prop" "!z10_fwd") ++ (eq_attr "z10prop" "!z10_fwd_A1")) ++ (and (and (and (eq_attr "z10prop" "!z10_fr_A3") ++ (eq_attr "z10prop" "!z10_fwd_A3")) ++ (and (eq_attr "z10prop" "!z10_fr") ++ (eq_attr "z10prop" "!z10_fr_E1"))) ++ (and (and (and (eq_attr "z10prop" "!z10_super") ++ (eq_attr "z10prop" "!z10_super_c")) ++ (eq_attr "z10prop" "!z10_super_c_E1")) ++ (and (eq_attr "z10prop" "!z10_super_E1") ++ (eq_attr "z10prop" "!z10_fwd_E1")))))) ++ "z10_e1_BOTH, z10_Gate_BOTH") ++ ++(define_insn_reservation "z10_other_fr_E1" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "other") ++ (eq_attr "z10prop" "z10_fr_E1"))) ++ "z10_e1_BOTH, z10_Gate_BOTH") ++ ++(define_insn_reservation "z10_other_super_c_E1" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "other") ++ (eq_attr "z10prop" "z10_super_c_E1"))) ++ "z10_e1_BOTH, z10_Gate_BOTH") ++ ++(define_insn_reservation "z10_other_super_E1" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "other") ++ (eq_attr "z10prop" "z10_super_E1"))) ++ "z10_e1_BOTH, z10_Gate_BOTH") ++ ++(define_insn_reservation "z10_other_fwd_E1" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "other") ++ (eq_attr "z10prop" "z10_fwd_E1"))) ++ "z10_e1_BOTH, z10_Gate_BOTH") ++ ++(define_insn_reservation "z10_other_fwd" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "other") ++ (eq_attr "z10prop" "z10_fwd"))) ++ "z10_e1_BOTH, z10_Gate_BOTH") ++ ++(define_insn_reservation "z10_other_fwd_A3" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "other") ++ (eq_attr "z10prop" "z10_fwd_A3"))) ++ "z10_e1_BOTH, z10_Gate_BOTH") ++ ++(define_insn_reservation "z10_other_fwd_A1" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "other") ++ (eq_attr "z10prop" "z10_fwd_A1"))) ++ "z10_e1_BOTH, z10_Gate_BOTH") ++ ++(define_insn_reservation "z10_other_fr" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "other") ++ (eq_attr "z10prop" "z10_fr"))) ++ "z10_e1_BOTH, z10_Gate_BOTH") ++ ++(define_insn_reservation "z10_other_fr_A3" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "other") ++ (eq_attr "z10prop" "z10_fr_A3"))) ++ "z10_e1_BOTH, z10_Gate_BOTH") ++ ++(define_insn_reservation "z10_other_super" 6 ++ (and (eq_attr "cpu" "z10") ++ (and (eq_attr "type" "other") ++ (ior (eq_attr "z10prop" "z10_super") ++ (eq_attr "z10prop" "z10_super_c")))) ++ "z10_e1_BOTH, z10_Gate_BOTH") ++ ++; END of z10_other subsets. ++ ++ ++; ++; Floating point insns ++; ++ ++; Z10 executes the following integer operations in the BFU pipeline. ++ ++(define_insn_reservation "z10_mul_sidi" 12 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "imulsi,imuldi,imulhi")) ++ "z10_e1_BOTH, z10_Gate_FP") ++ ++; Some variants take fewer cycles, but that is not relevant here. ++(define_insn_reservation "z10_div" 162 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "idiv")) ++ "z10_e1_BOTH*4, z10_Gate_FP") ++ ++ ++; BFP multiplication and general instructions ++ ++(define_insn_reservation "z10_fsimpdf" 12 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "fsimpdf,fmuldf")) ++ "z10_e1_BOTH, z10_Gate_FP") ++; Wg "z10_e1_T, z10_Gate_FP") ++ ++(define_insn_reservation "z10_fsimpsf" 12 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "fsimpsf,fmulsf")) ++ "z10_e1_BOTH, z10_Gate_FP") ++; Wg "z10_e1_T, z10_Gate_FP") ++ ++(define_insn_reservation "z10_fmultf" 52 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "fmultf")) ++ "z10_e1_BOTH*4, z10_Gate_FP") ++; Wg "z10_e1_T*4, z10_Gate_FP") ++ ++(define_insn_reservation "z10_fsimptf" 14 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "fsimptf")) ++ "z10_e1_BOTH*2, z10_Gate_FP") ++; Wg "z10_e1_T*2, z10_Gate_FP") ++ ++ ++; BFP division ++ ++(define_insn_reservation "z10_fdivtf" 113 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "fdivtf")) ++ "z10_e1_T*4, z10_Gate_FP") ++ ++(define_insn_reservation "z10_fdivdf" 41 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "fdivdf")) ++ "z10_e1_T*4, z10_Gate_FP") ++ ++(define_insn_reservation "z10_fdivsf" 34 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "fdivsf")) ++ "z10_e1_T*4, z10_Gate_FP") ++ ++ ++; BFP sqrt ++ ++(define_insn_reservation "z10_fsqrtsf" 41 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "fsqrtsf")) ++ "z10_e1_T*4, z10_Gate_FP") ++ ++(define_insn_reservation "z10_fsqrtdf" 54 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "fsqrtdf")) ++ "z10_e1_T*4, z10_Gate_FP") ++ ++(define_insn_reservation "z10_fsqrtf" 122 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "fsqrttf")) ++ "z10_e1_T*4, z10_Gate_FP") ++ ++ ++; BFP load and store ++ ++(define_insn_reservation "z10_floadtf" 12 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "floadtf")) ++ "z10_e1_T, z10_Gate_FP") ++ ++(define_insn_reservation "z10_floaddf" 12 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "floaddf")) ++ "z10_e1_T, z10_Gate_FP") ++ ++(define_insn_reservation "z10_floadsf" 12 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "floadsf")) ++ "z10_e1_T, z10_Gate_FP") ++ ++(define_insn_reservation "z10_fstoredf" 12 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "fstoredf,fstoredd")) ++ "z10_e1_T, z10_Gate_FP") ++ ++(define_insn_reservation "z10_fstoresf" 12 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "fstoresf,fstoresd")) ++ "z10_e1_T, z10_Gate_FP") ++ ++ ++; BFP truncate ++(define_insn_reservation "z10_ftrunctf" 12 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "ftrunctf")) ++ "z10_e1_T, z10_Gate_FP") ++ ++(define_insn_reservation "z10_ftruncdf" 16 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "ftruncdf")) ++ "z10_e1_T, z10_Gate_FP") ++ ++ ++; Conversion between BFP and int. ++(define_insn_reservation "z10_ftoi" 13 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "ftoi")) ++ "z10_e1_T, z10_Gate_FP") ++ ++(define_insn_reservation "z10_itoftf" 14 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "itoftf")) ++ "z10_e1_T*2, z10_Gate_FP") ++ ++(define_insn_reservation "z10_itofsfdf" 12 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "itofdf,itofsf")) ++ "z10_e1_T, z10_Gate_FP") ++ ++ ++ ++; BFP-related bypasses. There is no bypass for extended mode. ++(define_bypass 1 "z10_fsimpdf" "z10_fstoredf") ++(define_bypass 1 "z10_fsimpsf" "z10_fstoresf") ++(define_bypass 1 "z10_floaddf" "z10_fsimpdf, z10_fstoredf, z10_floaddf") ++(define_bypass 1 "z10_floadsf" "z10_fsimpsf, z10_fstoresf, z10_floadsf") ++ ++ ++; ++; insn_reservations for DFP instructions. ++; ++ ++; Exact number of cycles is not known at compile-time. ++(define_insn_reservation "z10_fdivddtd" 40 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "fdivdd,fdivtd")) ++ "z10_e1_BOTH,z10_Gate_DFU") ++ ++(define_insn_reservation "z10_ftruncsd" 38 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "ftruncsd")) ++ "z10_e1_BOTH*4,z10_Gate_DFU") ++ ++(define_insn_reservation "z10_ftruncdd" 340 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "ftruncsd")) ++ "z10_e1_BOTH*4,z10_Gate_DFU") ++ ++(define_insn_reservation "z10_floaddd" 12 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "floaddd")) ++ "z10_e1_BOTH,z10_Gate_DFU") ++ ++(define_insn_reservation "z10_floadsd" 12 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "floadsd")) ++ "z10_e1_BOTH,z10_Gate_DFU") ++ ++; Exact number of cycles is not known at compile-time. ++(define_insn_reservation "z10_fmulddtd" 35 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "fmuldd,fmultd")) ++ "z10_e1_BOTH,z10_Gate_DFU") ++ ++(define_insn_reservation "z10_fsimpdd" 17 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "fsimpdd")) ++ "z10_e1_BOTH,z10_Gate_DFU") ++ ++(define_insn_reservation "z10_fsimpsd" 17 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "fsimpsd")) ++ "z10_e1_BOTH,z10_Gate_DFU") ++ ++(define_insn_reservation "z10_fsimptd" 18 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "fsimptd")) ++ "z10_e1_BOTH,z10_Gate_DFU") ++ ++(define_insn_reservation "z10_itofdd" 36 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "itofdd")) ++ "z10_e1_BOTH*3,z10_Gate_DFU") ++ ++(define_insn_reservation "z10_itoftd" 49 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "itoftd")) ++ "z10_e1_BOTH*3,z10_Gate_DFU") ++ ++; Exact number of cycles is not known at compile-time. ++(define_insn_reservation "z10_ftoidfp" 30 ++ (and (eq_attr "cpu" "z10") ++ (eq_attr "type" "ftoidfp")) ++ "z10_e1_BOTH*3,z10_Gate_DFU") ++ ++ ++; ++; Address-related bypasses ++; ++ ++; Here is the cycle diagram for Address-related bypasses: ++; ... G1 G2 G3 A0 A1 A2 A3 E1 P1 P2 P3 R0 ... ++; ^ ^ ^ ^ ^ ++; | | | | E1-type bypasses provide the new addr AFTER this cycle ++; | | | A3-type bypasses provide the new addr AFTER this cycle ++; | | A1-type bypasses provide the new addr AFTER this cycle ++; | AGI resolution, actual USE of address is DURING this cycle ++; AGI detection ++ ++(define_bypass 3 "z10_larl_A1, z10_la_fwd_A1, z10_other_fwd_A1, \ ++ z10_int_fwd_A1" ++ "z10_agen, z10_la, z10_branch, z10_call, z10_load, \ ++ z10_store, \ ++ z10_cs, z10_stm, z10_other" ++ "s390_agen_dep_p") ++ ++ ++(define_bypass 5 "z10_larl_fwd_A3, z10_load_fwd_A3, z10_other_fwd_A3, \ ++ z10_other_fr_A3, z10_int_fwd_A3, z10_int_fr_A3" ++ "z10_agen, z10_la, z10_branch, z10_call, z10_load, \ ++ z10_store, \ ++ z10_cs, z10_stm, z10_other" ++ "s390_agen_dep_p") ++ ++(define_bypass 6 "z10_other_fr_E1, z10_other_super_c_E1, z10_other_super_E1, \ ++ z10_other_fwd_E1, \ ++ z10_lr_fr_E1, z10_larl_super_E1, \ ++ z10_int_super_E1, z10_int_fwd_E1, z10_int_fr_E1" ++ "z10_agen, z10_la, z10_branch, z10_call, z10_load, \ ++ z10_store, \ ++ z10_cs, z10_stm, z10_other" ++ "s390_agen_dep_p") ++ ++ ++ ++; ++; Try to avoid transitions between DFU-, BFU- and FXU-executed instructions as there is a ++; dispatch delay required. ++; ++ ++ ++; Declaration for some pseudo-pipeline stages that reflect the ++; dispatch gap when issueing an INT/FXU/BFU-executed instruction after ++; an instruction executed by a different unit has been executed. The ++; approach is that we pretend a pipelined execution of BFU operations ++; with as many stages as the gap is long and request that none of ++; these stages is busy when issueing a FXU- or DFU-executed ++; instruction. Similar for FXU- and DFU-executed instructions. ++ ++; Declaration for FPU stages. ++(define_cpu_unit "z10_f0, z10_f1, z10_f2, z10_f3, z10_f4, z10_f5, z10_f6, \ ++ z10_f7, z10_f8, z10_f9, z10_f10, z10_f11, z10_f12" "z10_cpu") ++(define_reservation "z10_FP_PP" "z10_f0, z10_f1, z10_f2, z10_f3, z10_f4, \ ++ z10_f5, z10_f6, z10_f7, z10_f8, z10_f9, z10_f10, z10_f11, \ ++ z10_f12") ++ ++; Declaration for FXU stages. ++(define_cpu_unit "z10_S1, z10_S2, z10_S3, z10_S4, z10_S5, z10_S6" "z10_cpu") ++(define_cpu_unit "z10_T1, z10_T2, z10_T3, z10_T4, z10_T5, z10_T6" "z10_cpu") ++(define_reservation "z10_INT_PP" "z10_S1 | z10_T1, z10_S2 | z10_T2, z10_S3 \ ++ | z10_T3, z10_S4 | z10_T4, z10_S5 | \ ++ z10_T5, z10_S6 | z10_T6") ++ ++; Declaration for DFU stages. ++(define_cpu_unit "z10_d0, z10_d1, z10_d2, z10_d3, z10_d4, z10_d5, z10_d6" ++ "z10_cpu") ++(define_reservation "z10_DFU_PP" "z10_d0, z10_d1, z10_d2, z10_d3, z10_d4, \ ++ z10_d5, z10_d6") ++ ++ ++; Pseudo-units representing whether the respective unit is available ++; in the sense that using it does not cause a dispatch delay. ++ ++(define_cpu_unit "z10_S_avail, z10_T_avail, z10_FP_avail, z10_DFU_avail" ++ "z10_cpu") ++ ++(absence_set "z10_FP_avail" ++ "z10_S1, z10_S2, z10_S3, z10_S4, z10_S5, z10_S6, z10_T1, z10_T2, z10_T3, z10_T4, \ ++ z10_T5, z10_T6, \ ++ z10_d0, z10_d1, z10_d2, z10_d3, z10_d4, z10_d5, z10_d6") ++ ++(absence_set "z10_S_avail,z10_T_avail" ++ "z10_f0, z10_f1, z10_f2, z10_f3, z10_f4, z10_f5, z10_f6, z10_f7, \ ++ z10_f8, z10_f9, z10_f10, z10_f11, z10_f12, \ ++ z10_d0, z10_d1, z10_d2, z10_d3, z10_d4, z10_d5, z10_d6") ++ ++(absence_set "z10_DFU_avail" ++ "z10_S1, z10_S2, z10_S3, z10_S4, z10_S5, z10_S6, z10_T1, z10_T2, z10_T3, z10_T4, \ ++ z10_T5, z10_T6, \ ++ z10_f0, z10_f1, z10_f2, z10_f3, z10_f4, z10_f5, z10_f6, z10_f7, \ ++ z10_f8, z10_f9, z10_f10, z10_f11, z10_f12") ++ ++ ++; Pseudo-units to be used in insn_reservations. ++ ++(define_reservation "z10_Gate_ANY" "((z10_S_avail | z10_T_avail), z10_INT_PP)") ++(define_reservation "z10_Gate_BOTH" "((z10_S_avail + z10_T_avail), z10_INT_PP)") ++ ++(define_reservation "z10_Gate_FP" "z10_FP_avail, z10_FP_PP") ++ ++(define_reservation "z10_Gate_DFU" "z10_DFU_avail, z10_DFU_PP") +Index: gcc/config/s390/constraints.md +=================================================================== +--- gcc/config/s390/constraints.md (revision 141434) ++++ gcc/config/s390/constraints.md (working copy) +@@ -1,5 +1,5 @@ + ;; Constraints definitions belonging to the gcc backend for IBM S/390. +-;; Copyright (C) 2006, 2007 Free Software Foundation, Inc. ++;; Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc. + ;; Written by Wolfgang Gellerich, using code and information found in + ;; files s390.md, s390.h, and s390.c. + ;; +@@ -24,10 +24,14 @@ + ;; Special constraints for s/390 machine description: + ;; + ;; a -- Any address register from 1 to 15. ++;; b -- Memory operand whose address is a symbol reference or a symbol ++;; reference + constant which can be proven to be naturally aligned. + ;; c -- Condition code register 33. + ;; d -- Any register from 0 to 15. + ;; f -- Floating point registers. + ;; t -- Access registers 36 and 37. ++;; C -- A signed 8-bit constant (-128..127) ++;; D -- An unsigned 16-bit constant (0..65535) + ;; G -- Const double zero operand + ;; I -- An 8-bit constant (0..255). + ;; J -- A 12-bit constant (0..4095). +@@ -102,6 +106,19 @@ + ;; General constraints for constants. + ;; + ++(define_constraint "C" ++ "@internal ++ An 8-bit signed immediate constant (-128..127)" ++ (and (match_code "const_int") ++ (match_test "ival >= -128 && ival <= 127"))) ++ ++ ++(define_constraint "D" ++ "An unsigned 16-bit constant (0..65535)" ++ (and (match_code "const_int") ++ (match_test "ival >= 0 && ival <= 65535"))) ++ ++ + (define_constraint "G" + "@internal + Const double zero operand" +@@ -127,7 +144,6 @@ + (match_test "ival >= -32768 && ival <= 32767"))) + + +- + (define_constraint "L" + "Value appropriate as displacement. + (0..4095) for short displacement +@@ -355,7 +371,6 @@ + (match_test "s390_mem_constraint (\"Q\", op)")) + + +- + (define_memory_constraint "R" + "Memory reference with index register and short displacement" + (match_test "s390_mem_constraint (\"R\", op)")) +@@ -371,7 +386,28 @@ + (match_test "s390_mem_constraint (\"T\", op)")) + + ++(define_memory_constraint "b" ++ "Memory reference whose address is a naturally aligned symbol reference." ++ (match_test "MEM_P (op) ++ && s390_check_symref_alignment (XEXP (op, 0), ++ GET_MODE_SIZE (GET_MODE (op)))")) + ++(define_memory_constraint "e" ++ "Matches all memory references available on the current architecture ++level. This constraint will never be used and using it in an inline ++assembly is *always* a bug since there is no instruction accepting all ++those addresses. It just serves as a placeholder for a generic memory ++constraint." ++ (match_test "legitimate_address_p (GET_MODE (op), op, 1)")) ++ ++; This defines 'm' as normal memory constraint. This is only possible ++; since the standard memory constraint is re-defined in s390.h using ++; the TARGET_MEM_CONSTRAINT macro. ++(define_memory_constraint "m" ++ "Matches the most general memory address for pre-z10 machines." ++ (match_test "s390_mem_constraint (\"R\", op) ++ || s390_mem_constraint (\"T\", op)")) ++ + (define_memory_constraint "AQ" + "@internal + Offsettable memory reference without index register and with short displacement" +@@ -425,7 +461,6 @@ + (match_test "s390_mem_constraint (\"BT\", op)")) + + +- + (define_address_constraint "U" + "Pointer with short displacement" + (match_test "s390_mem_constraint (\"U\", op)")) +Index: gcc/config/s390/s390-protos.h +=================================================================== +--- gcc/config/s390/s390-protos.h (revision 141434) ++++ gcc/config/s390/s390-protos.h (working copy) +@@ -1,5 +1,7 @@ + /* Definitions of target machine for GNU compiler, for IBM S/390. +- Copyright (C) 2000, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc. ++ Copyright (C) 2000, 2002, 2003, 2004, 2005, 2007, 2008 Free ++ Software Foundation, Inc. ++ + Contributed by Hartmut Penner (hpenner@de.ibm.com) + + This file is part of GCC. +@@ -27,9 +29,9 @@ + extern int s390_O_constraint_str (const char c, HOST_WIDE_INT value); + extern int s390_N_constraint_str (const char *str, HOST_WIDE_INT value); + extern int s390_float_const_zero_p (rtx value); ++extern bool s390_check_symref_alignment (rtx addr, HOST_WIDE_INT alignment); + + +- + /* Declare functions in s390.c. */ + + extern void optimization_options (int, int); +@@ -51,6 +53,7 @@ + extern int s390_const_double_ok_for_constraint_p (rtx, int, const char *); + extern int s390_single_part (rtx, enum machine_mode, enum machine_mode, int); + extern unsigned HOST_WIDE_INT s390_extract_part (rtx, enum machine_mode, int); ++extern bool s390_contiguous_bitmask_p (unsigned HOST_WIDE_INT, int, int *, int *); + extern bool s390_split_ok_p (rtx, rtx, enum machine_mode, int); + extern bool s390_overlap_p (rtx, rtx, HOST_WIDE_INT); + extern bool s390_offset_p (rtx, rtx, rtx); +@@ -80,6 +83,8 @@ + extern enum reg_class s390_secondary_output_reload_class (enum reg_class, + enum machine_mode, + rtx); ++extern void s390_reload_larl_operand (rtx , rtx , rtx); ++extern void s390_reload_symref_address (rtx , rtx , rtx , bool); + extern void s390_expand_plus_operand (rtx, rtx, rtx); + extern void emit_symbolic_move (rtx *); + extern void s390_load_address (rtx, rtx); +@@ -113,6 +118,7 @@ + extern bool s390_legitimate_address_without_index_p (rtx); + extern bool s390_decompose_shift_count (rtx, rtx *, HOST_WIDE_INT *); + extern int s390_branch_condition_mask (rtx); ++extern int s390_compare_and_branch_condition_mask (rtx); + + #endif /* RTX_CODE */ + +Index: gcc/stmt.c +=================================================================== +--- gcc/stmt.c (revision 141434) ++++ gcc/stmt.c (working copy) +@@ -364,7 +364,7 @@ + } + break; + +- case 'V': case 'm': case 'o': ++ case 'V': case TARGET_MEM_CONSTRAINT: case 'o': + *allows_mem = true; + break; + +@@ -463,7 +463,7 @@ + } + break; + +- case 'V': case 'm': case 'o': ++ case 'V': case TARGET_MEM_CONSTRAINT: case 'o': + *allows_mem = true; + break; + +Index: gcc/reload1.c +=================================================================== +--- gcc/reload1.c (revision 141434) ++++ gcc/reload1.c (working copy) +@@ -1455,11 +1455,11 @@ + switch (c) + { + case '=': case '+': case '*': case '%': case '?': case '!': +- case '0': case '1': case '2': case '3': case '4': case 'm': +- case '<': case '>': case 'V': case 'o': case '&': case 'E': +- case 'F': case 's': case 'i': case 'n': case 'X': case 'I': +- case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': +- case 'P': ++ case '0': case '1': case '2': case '3': case '4': case '<': ++ case '>': case 'V': case 'o': case '&': case 'E': case 'F': ++ case 's': case 'i': case 'n': case 'X': case 'I': case 'J': ++ case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': ++ case TARGET_MEM_CONSTRAINT: + break; + + case 'p': diff --git a/4.3.2/gentoo/73_all_sh-libgcc-stacks.patch b/4.3.2/gentoo/73_all_sh-libgcc-stacks.patch new file mode 100644 index 0000000..4ea628a --- /dev/null +++ b/4.3.2/gentoo/73_all_sh-libgcc-stacks.patch @@ -0,0 +1,44 @@ +make sure objects in libgcc.a have GNU-stack markings: +!WX --- --- 4.3.2/_ashiftrt.o +!WX --- --- 4.3.2/_ashiftrt_n.o +!WX --- --- 4.3.2/_ashiftlt.o +!WX --- --- 4.3.2/_lshiftrt.o +!WX --- --- 4.3.2/_movmem.o +!WX --- --- 4.3.2/_movmem_i4.o +!WX --- --- 4.3.2/_mulsi3.o +!WX --- --- 4.3.2/_sdivsi3.o +!WX --- --- 4.3.2/_sdivsi3_i4.o +!WX --- --- 4.3.2/_udivsi3.o +!WX --- --- 4.3.2/_udivsi3_i4.o +!WX --- --- 4.3.2/_set_fpscr.o +!WX --- --- 4.3.2/_div_table.o +!WX --- --- 4.3.2/_udiv_qrnnd_16.o +!WX --- --- 4.3.2/_ic_invalidate.o +!WX --- --- 4.3.2/_ic_invalidate_array.o +!WX --- --- 4.3.2/linux-atomic.o + +--- gcc/config/sh/lib1funcs.asm ++++ gcc/config/sh/lib1funcs.asm +@@ -34,6 +34,11 @@ + !! recoded in assembly by Toshiyasu Morita + !! tm@netcom.com + ++#if defined(__ELF__) && defined(__linux__) ++.section .note.GNU-stack,"",%progbits ++.previous ++#endif ++ + /* SH2 optimizations for ___ashrsi3, ___ashlsi3, ___lshrsi3 and + ELF local label prefixes by J"orn Rennecke + amylaar@cygnus.com */ +--- gcc/config/sh/linux-atomic.asm ++++ gcc/config/sh/linux-atomic.asm +@@ -138,3 +138,8 @@ + ATOMIC_FETCH_AND_COMBOP(nand,and,not,4,l,mov) + + #endif /* ! __SH5__ */ ++ ++#if defined(__ELF__) && defined(__linux__) ++.section .note.GNU-stack,"",%progbits ++.previous ++#endif diff --git a/4.3.2/gentoo/README.history b/4.3.2/gentoo/README.history index a83a3bc..d4bb847 100644 --- a/4.3.2/gentoo/README.history +++ b/4.3.2/gentoo/README.history @@ -1,7 +1,9 @@ 1.3 [pending] + 15_all_gcc-libgomp-no-werror.patch + + 20_all_s390-gcc-4.3.2-z10-complete.patch + 45_all_arm-pic-ssp-segv-pr35965.patch + 67_all_gcc43-PR37408.patch + + 73_all_sh-libgcc-stacks.patch + 80_all_sparc-biarch.patch + 90_all_gcc-freebsd.patch + 91_all_gcc-freebsd.patch |