This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Further CCmode improvements for S/390


Hello,

this patch adds a couple of specialized CCmodes to the s390 backend that
allow better exploitation of the condition code set by some instructions,
notably the TM (test-under-mask) family and the AL/SL instructions.

The full range of condition codes for TMxx should now be exploited
(e.g. a check 'if ((a & 8) && !(a & 32))' is compiled into a single
TML followed by a branch).  For AL/SL, both checks for result zero
and for overflow (e.g. 'if (a + b < a)') are exploited.

Also, several 64-bit instructions of the *GF* type are now used
(ltgfr, cgf(r), clgf(r), agf(r), algf(r), sgf(r), slgf(r) msgf(r))
where appropriate.  The pattern for the CH instruction is also
fixed now so it is in fact used.

Finally, the whole section of comparison instructions is cleaned up
a bit and arranged somewhat differently.

Bootstrapped/regtested on s390-ibm-linux and s390x-ibm-linux.

Bye,
Ulrich

ChangeLog:

      * s390-modes.def [CCL1, CCL2, CCT1, CCT2, CCT3, CCUR, CCSR]: Declare
      new condition code modes.
      s390.c (s390_match_ccmode_set): Handle those new CC modes.
      (s390_select_ccmode): Likewise.
      (s390_branch_condition_mask): Likewise.

      * s390-protos.h (s390_tm_ccmode): Declare.
      s390.c (s390_tm_ccmode): New function.
      (s390_match_ccmode): Allow VOIDmode as REQ_MODE.

      * s390.md ("*cmpdi_tm2"): Rename to "*tmdi_ext".
      ("*cmpsi_tm2"): Rename to "*tmsi_ext".
      ("*cmpqi_tm2"): Rename to "*tmqi_ext".

      ("*cmpdi_tm_reg", "*cmpdi_tm_mem", "*cmpsi_tm_reg", "*cmpsi_tm_mem",
      "*cmphi_tm_sub","*cmphi_cct_0",  "*cmpqi_tm", "*cmpqi_tm_sub",
      "*cmpqi_cct_0", "*tm_0"): Remove, replace by ...
      ("*tmdi_reg", "*tmsi_reg", "*tmdi_mem", "*tmsi_mem", "*tmhi_mem",
      "*tmqi_mem", "*tmhi_full", "*tmqi_full"): ... these new patterns.

      ("*ltgr", "*cmpdi_ccs_0_64", "*cmpdi_ccs_0_31", "*ltr", "*icm15",
      "*icm15_cconly", "*cmpsi_ccs_0", "*icm3", "*cmphi_ccs_0", "*icm1",
      "*cmpqi_ccs_0"): Remove, replace by ...
      ("*tstdi_sign", "*tstdi", "*tstdi_cconly", "*tstdi_cconly_31",
      "*tstsi", "*tstsi_cconly", "*tstsi_cconly2", "*tsthi", "
*tsthi_cconly",
      "*tstqi", "*tstqi_cconly"): ... these new patterns.

      ("*cmpsidi_ccs"): Remove, replace by ...
      ("*cmpsi_ccs_sign"): ... this new pattern.
      ("*cmpdi_ccs_sign", "*cmpdi_ccu_zero"): New patterns.

      ("*cmpqi_ccu_0", "*cmpqi_ccu_immed"): Remove, replace by ...
      ("*cli"): ... this new pattern.

      ("*adddi3_sign", "*adddi3_zero_cc", "*adddi3_zero_cconly",
      "*adddi3_zero", "*adddi3_cc", "*adddi3_cconly", "*adddi3_cconly2"):
      New patterns.
      ("adddi3_64"): Rename to "*adddi3_64".
      ("adddi3_31"): Replace by insn and splitter "*adddi3_31".
      ("adddi3"): Adapt expander.

      ("*addsi3_cc"): Allow "general_operand" for operand 2.
      ("*addsi3_carry1_cc", "*addsi3_carry1_cconly",
      "*addsi3_carry2_cc", "*addsi3_carry2_cconly"): New patterns.

      ("addhi3", "addqi3"): Remove, replace by ...
      ("*addsi3_sign", "*addsi3_sub"): ... these new patterns.

      ("*subdi3_sign", "*subdi3_zero_cc", "*subdi3_zero_cconly",
      "*subdi3_zero", "*subdi3_cc", "*subdi3_cconly"): New patterns.
      ("subdi3"): Replace by insn and splitter "*subdi3_31".
      ("subdi3"): New expander.

      ("*subsi3_borrow_cc", "*subsi3_borrow_cconly"): New patterns.

      ("subhi3", "subqi3"): Remove, replace by ...
      ("*subsi3_sign", "*subsi3_sub"): ... these new patterns.

      ("*muldi3_sign"): New pattern.
      ("muldi3"): Do not clobber CC.
      ("mulsi3"): Likewise.
      ("mulsi_6432"): Likewise.

Index: gcc/config/s390/s390-modes.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390-modes.def,v
retrieving revision 1.1
diff -c -p -r1.1 s390-modes.def
*** gcc/config/s390/s390-modes.def  10 Jun 2002 22:35:55 -0000    1.1
--- gcc/config/s390/s390-modes.def  13 Aug 2002 15:38:22 -0000
*************** Boston, MA 02111-1307, USA.  */
*** 24,29 ****
--- 24,36 ----
  CC (CCZ)
  CC (CCA)
  CC (CCL)
+ CC (CCL1)
+ CC (CCL2)
  CC (CCU)
+ CC (CCUR)
  CC (CCS)
+ CC (CCSR)
  CC (CCT)
+ CC (CCT1)
+ CC (CCT2)
+ CC (CCT3)
Index: gcc/config/s390/s390-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390-protos.h,v
retrieving revision 1.9
diff -c -p -r1.9 s390-protos.h
*** gcc/config/s390/s390-protos.h   16 Jul 2002 20:59:04 -0000    1.9
--- gcc/config/s390/s390-protos.h   13 Aug 2002 15:38:22 -0000
*************** extern int s390_single_qi PARAMS ((rtx,
*** 46,51 ****
--- 46,52 ----
  extern int s390_extract_qi PARAMS ((rtx, enum machine_mode, int));

  extern int s390_match_ccmode PARAMS ((rtx, enum machine_mode));
+ extern enum machine_mode s390_tm_ccmode PARAMS ((rtx, rtx, int));
  extern enum machine_mode s390_select_ccmode PARAMS ((enum rtx_code, rtx,
rtx));
  extern int symbolic_reference_mentioned_p PARAMS ((rtx));
  extern int legitimate_la_operand_p PARAMS ((rtx));
Index: gcc/config/s390/s390.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.c,v
retrieving revision 1.44
diff -c -p -r1.44 s390.c
*** gcc/config/s390/s390.c    11 Aug 2002 18:48:51 -0000    1.44
--- gcc/config/s390/s390.c    13 Aug 2002 15:38:25 -0000
*************** s390_match_ccmode_set (set, req_mode)
*** 172,190 ****
    switch (set_mode)
      {
      case CCSmode:
!       if (req_mode != CCSmode)
!         return 0;
!       break;
      case CCUmode:
!       if (req_mode != CCUmode)
!         return 0;
!       break;
      case CCLmode:
!       if (req_mode != CCLmode)
          return 0;
        break;
      case CCZmode:
!       if (req_mode != CCSmode && req_mode != CCUmode && req_mode !=
CCTmode)
          return 0;
        break;

--- 172,193 ----
    switch (set_mode)
      {
      case CCSmode:
!     case CCSRmode:
      case CCUmode:
!     case CCURmode:
      case CCLmode:
!     case CCL1mode:
!     case CCL2mode:
!     case CCT1mode:
!     case CCT2mode:
!     case CCT3mode:
!       if (req_mode != set_mode)
          return 0;
        break;
+
      case CCZmode:
!       if (req_mode != CCSmode && req_mode != CCUmode && req_mode !=
CCTmode
!       && req_mode != CCSRmode && req_mode != CCURmode)
          return 0;
        break;

*************** s390_match_ccmode_set (set, req_mode)
*** 197,203 ****

  /* Return true if every SET in INSN that sets the CC register
     has source and destination with matching CC modes and that
!    CC mode is at least as constrained as REQ_MODE.  */

  int
  s390_match_ccmode (insn, req_mode)
--- 200,207 ----

  /* Return true if every SET in INSN that sets the CC register
     has source and destination with matching CC modes and that
!    CC mode is at least as constrained as REQ_MODE.
!    If REQ_MODE is VOIDmode, always return false.  */

  int
  s390_match_ccmode (insn, req_mode)
*************** s390_match_ccmode (insn, req_mode)
*** 206,211 ****
--- 210,219 ----
  {
    int i;

+   /* s390_tm_ccmode returns VOIDmode to indicate failure.  */
+   if (req_mode == VOIDmode)
+     return 0;
+
    if (GET_CODE (PATTERN (insn)) == SET)
      return s390_match_ccmode_set (PATTERN (insn), req_mode);

*************** s390_match_ccmode (insn, req_mode)
*** 221,226 ****
--- 229,273 ----
    return 1;
  }

+ /* If a test-under-mask instruction can be used to implement
+    (compare (and ... OP1) OP2), return the CC mode required
+    to do that.  Otherwise, return VOIDmode.
+    MIXED is true if the instruction can distinguish between
+    CC1 and CC2 for mixed selected bits (TMxx), it is false
+    if the instruction cannot (TM).  */
+
+ enum machine_mode
+ s390_tm_ccmode (op1, op2, mixed)
+      rtx op1;
+      rtx op2;
+      int mixed;
+ {
+   int bit0, bit1;
+
+   /* ??? Fixme: should work on CONST_DOUBLE as well.  */
+   if (GET_CODE (op1) != CONST_INT || GET_CODE (op2) != CONST_INT)
+     return VOIDmode;
+
+   /* Selected bits all zero: CC0.  */
+   if (INTVAL (op2) == 0)
+     return CCTmode;
+
+   /* Selected bits all one: CC3.  */
+   if (INTVAL (op2) == INTVAL (op1))
+     return CCT3mode;
+
+   /* Exactly two bits selected, mixed zeroes and ones: CC1 or CC2.  */
+   if (mixed)
+     {
+       bit1 = exact_log2 (INTVAL (op2));
+       bit0 = exact_log2 (INTVAL (op1) ^ INTVAL (op2));
+       if (bit0 != -1 && bit1 != -1)
+         return bit0 > bit1 ? CCT1mode : CCT2mode;
+     }
+
+   return VOIDmode;
+ }
+
  /* Given a comparison code OP (EQ, NE, etc.) and the operands
     OP0 and OP1 of a COMPARE, return the mode to be used for the
     comparison.  */
*************** s390_select_ccmode (code, op0, op1)
*** 239,244 ****
--- 286,313 ----
          || GET_CODE (op1) == NEG)
        return CCLmode;

+     if (GET_CODE (op0) == AND)
+       {
+         /* Check whether we can potentially do it via TM.  */
+         enum machine_mode ccmode;
+         ccmode = s390_tm_ccmode (XEXP (op0, 1), op1, 1);
+         if (ccmode != VOIDmode)
+           {
+           /* Relax CCTmode to CCZmode to allow fall-back to AND
+              if that turns out to be beneficial.  */
+             return ccmode == CCTmode ? CCZmode : ccmode;
+           }
+       }
+
+     if (register_operand (op0, HImode)
+         && GET_CODE (op1) == CONST_INT
+         && (INTVAL (op1) == -1 || INTVAL (op1) == 65535))
+       return CCT3mode;
+     if (register_operand (op0, QImode)
+         && GET_CODE (op1) == CONST_INT
+         && (INTVAL (op1) == -1 || INTVAL (op1) == 255))
+       return CCT3mode;
+
      return CCZmode;

        case LE:
*************** s390_select_ccmode (code, op0, op1)
*** 253,264 ****
        case UNGE:
        case UNGT:
        case LTGT:
      return CCSmode;

-       case LEU:
        case LTU:
        case GEU:
        case GTU:
      return CCUmode;

        default:
--- 322,350 ----
        case UNGE:
        case UNGT:
        case LTGT:
+     if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
+         && GET_CODE (op1) != CONST_INT)
+       return CCSRmode;
      return CCSmode;

        case LTU:
        case GEU:
+     if (GET_CODE (op0) == PLUS)
+       return CCL1mode;
+
+     if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
+         && GET_CODE (op1) != CONST_INT)
+       return CCURmode;
+     return CCUmode;
+
+       case LEU:
        case GTU:
+     if (GET_CODE (op0) == MINUS)
+       return CCL2mode;
+
+     if ((GET_CODE (op0) == SIGN_EXTEND || GET_CODE (op0) == ZERO_EXTEND)
+         && GET_CODE (op1) != CONST_INT)
+       return CCURmode;
      return CCUmode;

        default:
*************** s390_branch_condition_mask (code)
*** 295,307 ****
          }
        break;

      case CCLmode:
        switch (GET_CODE (code))
          {
          case EQ:      return CC0 | CC2;
      case NE:    return CC1 | CC3;
!     case UNORDERED:   return CC2 | CC3;  /* carry */
!     case ORDERED:     return CC0 | CC1;  /* no carry */
      default:
        abort ();
          }
--- 381,441 ----
          }
        break;

+     case CCT1mode:
+       switch (GET_CODE (code))
+         {
+         case EQ:      return CC1;
+     case NE:    return CC0 | CC2 | CC3;
+     default:
+       abort ();
+         }
+       break;
+
+     case CCT2mode:
+       switch (GET_CODE (code))
+         {
+         case EQ:      return CC2;
+     case NE:    return CC0 | CC1 | CC3;
+     default:
+       abort ();
+         }
+       break;
+
+     case CCT3mode:
+       switch (GET_CODE (code))
+         {
+         case EQ:      return CC3;
+     case NE:    return CC0 | CC1 | CC2;
+     default:
+       abort ();
+         }
+       break;
+
      case CCLmode:
        switch (GET_CODE (code))
          {
          case EQ:      return CC0 | CC2;
      case NE:    return CC1 | CC3;
!     default:
!       abort ();
!         }
!       break;
!
!     case CCL1mode:
!       switch (GET_CODE (code))
!         {
!     case LTU:   return CC2 | CC3;  /* carry */
!     case GEU:   return CC0 | CC1;  /* no carry */
!     default:
!       abort ();
!         }
!       break;
!
!     case CCL2mode:
!       switch (GET_CODE (code))
!         {
!     case GTU:   return CC0 | CC1;  /* borrow */
!     case LEU:   return CC2 | CC3;  /* no borrow */
      default:
        abort ();
          }
*************** s390_branch_condition_mask (code)
*** 321,326 ****
--- 455,474 ----
          }
        break;

+     case CCURmode:
+       switch (GET_CODE (code))
+         {
+         case EQ:      return CC0;
+         case NE:      return CC2 | CC1 | CC3;
+         case LTU:     return CC2;
+         case GTU:     return CC1;
+         case LEU:     return CC0 | CC2;
+         case GEU:     return CC0 | CC1;
+     default:
+       abort ();
+         }
+       break;
+
      case CCSmode:
        switch (GET_CODE (code))
          {
*************** s390_branch_condition_mask (code)
*** 341,346 ****
--- 489,517 ----
      default:
        abort ();
          }
+       break;
+
+     case CCSRmode:
+       switch (GET_CODE (code))
+         {
+         case EQ:      return CC0;
+         case NE:      return CC2 | CC1 | CC3;
+         case LT:      return CC2;
+         case GT:      return CC1;
+         case LE:      return CC0 | CC2;
+         case GE:      return CC0 | CC1;
+     case UNORDERED:   return CC3;
+     case ORDERED:     return CC0 | CC2 | CC1;
+     case UNEQ:  return CC0 | CC3;
+         case UNLT:    return CC2 | CC3;
+         case UNGT:    return CC1 | CC3;
+         case UNLE:    return CC0 | CC2 | CC3;
+         case UNGE:    return CC0 | CC1 | CC3;
+     case LTGT:  return CC2 | CC1;
+     default:
+       abort ();
+         }
+       break;

      default:
        abort ();
Index: gcc/config/s390/s390.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.md,v
retrieving revision 1.22
diff -c -p -r1.22 s390.md
*** gcc/config/s390/s390.md   11 Jun 2002 14:47:04 -0000    1.22
--- gcc/config/s390/s390.md   13 Aug 2002 15:38:29 -0000
***************
*** 191,220 ****
    DONE;
  }")

- ;(define_expand "cmphi"
- ;  [(set (reg:CC 33)
- ;        (compare:CC (match_operand:HI 0 "register_operand" "")
- ;                    (match_operand:HI 1 "general_operand" "")))]
- ;  ""
- ;  "
- ;{
- ;  s390_compare_op0 = operands[0];
- ;  s390_compare_op1 = operands[1];
- ;  DONE;
- ;}")
-
- ;(define_expand "cmpqi"
- ;  [(set (reg:CC 33)
- ;        (compare:CC (match_operand:QI 0 "register_operand" "")
- ;                    (match_operand:QI 1 "general_operand" "")))]
- ;  ""
- ;  "
- ;{
- ;  s390_compare_op0 = operands[0];
- ;  s390_compare_op1 = operands[1];
- ;  DONE;
- ;}")
-
  (define_expand "cmpdf"
    [(set (reg:CC 33)
          (compare:CC (match_operand:DF 0 "register_operand" "")
--- 191,196 ----
***************
*** 240,248 ****
  }")


! ; DI instructions

! (define_insn "*cmpdi_tm2"
    [(set (reg 33)
          (compare (zero_extract:DI (match_operand:DI 0 "register_operand"
"d")
                                (match_operand:DI 1 "const_int_operand"
"n")
--- 216,224 ----
  }")


! ; Test-under-Mask (zero_extract) instructions

! (define_insn "*tmdi_ext"
    [(set (reg 33)
          (compare (zero_extract:DI (match_operand:DI 0 "register_operand"
"d")
                                (match_operand:DI 1 "const_int_operand"
"n")
***************
*** 272,413 ****
  }"
    [(set_attr "op_type" "RI")])

! (define_insn "*cmpdi_tm_reg"
    [(set (reg 33)
!         (compare (and:DI (match_operand:DI 0 "register_operand" "%d")
!                          (match_operand:DI 1 "immediate_operand" "n"))
                   (const_int 0)))]
!   "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT
!    && s390_single_hi (operands[1], DImode, 0) >= 0"
    "*
  {
!   int part = s390_single_hi (operands[1], DImode, 0);
!   operands[1] = GEN_INT (s390_extract_hi (operands[1], DImode, part));

    switch (part)
      {
!       case 0: return \"tmhh\\t%0,%x1\";
!       case 1: return \"tmhl\\t%0,%x1\";
!       case 2: return \"tmlh\\t%0,%x1\";
!       case 3: return \"tmll\\t%0,%x1\";
        default: abort ();
      }
  }"
    [(set_attr "op_type" "RI")])

! (define_insn "*cmpdi_tm_mem"
    [(set (reg 33)
!         (compare (and:DI (match_operand:DI 0 "s_operand" "%Qo")
!                          (match_operand:DI 1 "immediate_operand" "n"))
                   (const_int 0)))]
!   "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT
!    && s390_single_qi (operands[1], DImode, 0) >= 0"
    "*
  {
!   int part = s390_single_qi (operands[1], DImode, 0);
!   operands[1] = GEN_INT (s390_extract_qi (operands[1], DImode, part));


!   operands[0] = gen_rtx_MEM (QImode,
!                      plus_constant (XEXP (operands[0], 0), part));
!   return \"tm\\t%0,%b1\";
  }"
    [(set_attr "op_type" "SI")
     (set_attr "atype"   "mem")])

! (define_insn "*ltgr"
!   [(set (reg 33)
!         (compare (match_operand:DI 0 "register_operand" "d")
!                  (match_operand:DI 1 "const0_operand" "")))
!    (set (match_operand:DI 2 "register_operand" "=d")
!         (match_dup 0))]
!   "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
!   "ltgr\\t%2,%0"
!   [(set_attr "op_type" "RRE")])
!
! (define_insn "*cmpdi_ccs_0_64"
!   [(set (reg 33)
!         (compare (match_operand:DI 0 "register_operand" "d")
!                  (match_operand:DI 1 "const0_operand" "")))]
!   "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
!   "ltgr\\t%0,%0"
!   [(set_attr "op_type" "RRE")])

! (define_insn "*cmpdi_ccs_0_31"
    [(set (reg 33)
!         (compare (match_operand:DI 0 "register_operand" "d")
!                  (match_operand:DI 1 "const0_operand" "")))]
!   "s390_match_ccmode(insn, CCSmode)"
!   "srda\\t%0,0"
!   [(set_attr "op_type" "RS")])
!
! (define_insn "*cmpdi_ccs"
!   [(set (reg 33)
!         (compare (match_operand:DI 0 "register_operand" "d,d,d")
!                  (match_operand:DI 1 "general_operand" "d,K,m")))]
!   "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
!   "@
!    cgr\\t%0,%1
!    cghi\\t%0,%c1
!    cg\\t%0,%1"
!   [(set_attr "op_type" "RRE,RI,RXE")
!    (set_attr "atype"    "reg,reg,mem")])
!
! (define_insn "*cmpdi_ccu"
!   [(set (reg 33)
!         (compare (match_operand:DI 0 "register_operand" "d,d")
!                  (match_operand:DI 1 "general_operand" "d,m")))]
!   "s390_match_ccmode(insn, CCUmode) && TARGET_64BIT"
!   "@
!    clgr\\t%0,%1
!    clg\\t%0,%1"
!   [(set_attr "op_type" "RRE,RXE")
!    (set_attr "atype"   "reg,mem")])
!
! (define_insn "*cmpdi_ccu_mem"
!   [(set (reg 33)
!         (compare (match_operand:DI 0 "s_operand" "oQ")
!                  (match_operand:DI 1 "s_imm_operand" "oQ")))]
!   "s390_match_ccmode(insn, CCUmode)"
!   "clc\\t%O0(8,%R0),%1"
!   [(set_attr "op_type" "SS")
!    (set_attr "atype"   "mem")])
!
! ; SI instructions
!
! (define_insn "*cmpsi_tm2"
!   [(set (reg 33)
!         (compare (zero_extract:SI (match_operand:SI 0 "register_operand"
"d")
!                               (match_operand:SI 1 "const_int_operand"
"n")
!                                   (match_operand:SI 2 "const_int_operand"
"n"))
!                  (const_int 0)))]
!   "s390_match_ccmode(insn, CCTmode)
!    && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0
!    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
!    && (INTVAL (operands[1]) + INTVAL (operands[2]) - 1) >> 4
!       == INTVAL (operands[2]) >> 4"
    "*
  {
!   int part = INTVAL (operands[2]) >> 4;
!   int block = (1 << INTVAL (operands[1])) - 1;
!   int shift = 16 - INTVAL (operands[1]) - (INTVAL (operands[2]) & 15);
!
!   operands[2] = GEN_INT (block << shift);

    switch (part)
      {
!       case 0: return \"tmh\\t%0,%x2\";
!       case 1: return \"tml\\t%0,%x2\";
        default: abort ();
      }
  }"
    [(set_attr "op_type" "RI")])

! (define_insn "*cmpsi_tm_reg"
    [(set (reg 33)
          (compare (and:SI (match_operand:SI 0 "register_operand" "%d")
                           (match_operand:SI 1 "immediate_operand" "n"))
!                  (const_int 0)))]
!   "s390_match_ccmode(insn, CCTmode)
     && s390_single_hi (operands[1], SImode, 0) >= 0"
    "*
  {
--- 248,333 ----
  }"
    [(set_attr "op_type" "RI")])

! (define_insn "*tmsi_ext"
    [(set (reg 33)
!         (compare (zero_extract:SI (match_operand:SI 0 "register_operand"
"d")
!                               (match_operand:SI 1 "const_int_operand"
"n")
!                                   (match_operand:SI 2 "const_int_operand"
"n"))
                   (const_int 0)))]
!   "s390_match_ccmode(insn, CCTmode)
!    && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0
!    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
!    && (INTVAL (operands[1]) + INTVAL (operands[2]) - 1) >> 4
!       == INTVAL (operands[2]) >> 4"
    "*
  {
!   int part = INTVAL (operands[2]) >> 4;
!   int block = (1 << INTVAL (operands[1])) - 1;
!   int shift = 16 - INTVAL (operands[1]) - (INTVAL (operands[2]) & 15);
!
!   operands[2] = GEN_INT (block << shift);

    switch (part)
      {
!       case 0: return \"tmh\\t%0,%x2\";
!       case 1: return \"tml\\t%0,%x2\";
        default: abort ();
      }
  }"
    [(set_attr "op_type" "RI")])

! (define_insn "*tmqi_ext"
    [(set (reg 33)
!         (compare (zero_extract:SI (match_operand:QI 0 "s_operand" "Qo")
!                               (match_operand:SI 1 "const_int_operand"
"n")
!                                   (match_operand:SI 2 "const_int_operand"
"n"))
                   (const_int 0)))]
!   "s390_match_ccmode(insn, CCTmode)
!    && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0
!    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 8"
    "*
  {
!   int block = (1 << INTVAL (operands[1])) - 1;
!   int shift = 8 - INTVAL (operands[1]) - INTVAL (operands[2]);

!   operands[2] = GEN_INT (block << shift);
!   return \"tm\\t%0,%b2\";
  }"
    [(set_attr "op_type" "SI")
     (set_attr "atype"   "mem")])

! ; Test-under-Mask instructions

! (define_insn "*tmdi_reg"
    [(set (reg 33)
!         (compare (and:DI (match_operand:DI 0 "register_operand" "%d")
!                          (match_operand:DI 1 "immediate_operand" "n"))
!                  (match_operand:DI 2 "immediate_operand" "n")))]
!   "TARGET_64BIT
!    && s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2],
1))
!    && s390_single_hi (operands[1], DImode, 0) >= 0"
    "*
  {
!   int part = s390_single_hi (operands[1], DImode, 0);
!   operands[1] = GEN_INT (s390_extract_hi (operands[1], DImode, part));

    switch (part)
      {
!       case 0: return \"tmhh\\t%0,%x1\";
!       case 1: return \"tmhl\\t%0,%x1\";
!       case 2: return \"tmlh\\t%0,%x1\";
!       case 3: return \"tmll\\t%0,%x1\";
        default: abort ();
      }
  }"
    [(set_attr "op_type" "RI")])

! (define_insn "*tmsi_reg"
    [(set (reg 33)
          (compare (and:SI (match_operand:SI 0 "register_operand" "%d")
                           (match_operand:SI 1 "immediate_operand" "n"))
!                  (match_operand:SI 2 "immediate_operand" "n")))]
!   "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 1))
     && s390_single_hi (operands[1], SImode, 0) >= 0"
    "*
  {
***************
*** 423,434 ****
  }"
    [(set_attr "op_type" "RI")])

! (define_insn "*cmpsi_tm_mem"
    [(set (reg 33)
          (compare (and:SI (match_operand:SI 0 "s_operand" "%Qo")
                           (match_operand:SI 1 "immediate_operand" "n"))
!                  (const_int 0)))]
!   "s390_match_ccmode(insn, CCTmode)
     && s390_single_qi (operands[1], SImode, 0) >= 0"
    "*
  {
--- 343,374 ----
  }"
    [(set_attr "op_type" "RI")])

! (define_insn "*tmdi_mem"
!   [(set (reg 33)
!         (compare (and:DI (match_operand:DI 0 "s_operand" "%Qo")
!                          (match_operand:DI 1 "immediate_operand" "n"))
!                  (match_operand:DI 2 "immediate_operand" "n")))]
!   "TARGET_64BIT
!    && s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2],
0))
!    && s390_single_qi (operands[1], DImode, 0) >= 0"
!   "*
! {
!   int part = s390_single_qi (operands[1], DImode, 0);
!   operands[1] = GEN_INT (s390_extract_qi (operands[1], DImode, part));
!
!   operands[0] = gen_rtx_MEM (QImode,
!                      plus_constant (XEXP (operands[0], 0), part));
!   return \"tm\\t%0,%b1\";
! }"
!   [(set_attr "op_type" "SI")
!    (set_attr "atype"   "mem")])
!
! (define_insn "*tmsi_mem"
    [(set (reg 33)
          (compare (and:SI (match_operand:SI 0 "s_operand" "%Qo")
                           (match_operand:SI 1 "immediate_operand" "n"))
!                  (match_operand:SI 2 "immediate_operand" "n")))]
!   "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))
     && s390_single_qi (operands[1], SImode, 0) >= 0"
    "*
  {
***************
*** 442,550 ****
    [(set_attr "op_type" "SI")
     (set_attr "atype"   "mem")])

! (define_insn "*ltr"
    [(set (reg 33)
!         (compare (match_operand:SI 0 "register_operand" "d")
!                  (match_operand:SI 1 "const0_operand" "")))
!    (set (match_operand:SI 2 "register_operand" "=d")
!         (match_dup 0))]
!   "s390_match_ccmode(insn, CCSmode)"
!   "ltr\\t%2,%0"
!   [(set_attr "op_type" "RR")])

! (define_insn "*icm15"
!   [(set (reg 33)
!         (compare (match_operand:SI 0 "s_operand" "Qo")
!                  (match_operand:SI 1 "const0_operand" "")))
!    (set (match_operand:SI 2 "register_operand" "=d")
!         (match_dup 0))]
!   "s390_match_ccmode(insn, CCSmode)"
!   "icm\\t%2,15,%0"
!   [(set_attr "op_type" "RS")
     (set_attr "atype"   "mem")])

! (define_insn "*icm15_cconly"
    [(set (reg 33)
!         (compare (match_operand:SI 0 "s_operand" "Qo")
!                  (match_operand:SI 1 "const0_operand" "")))
!    (clobber (match_scratch:SI 2 "=d"))]
!   "s390_match_ccmode(insn, CCSmode)"
!   "icm\\t%2,15,%0"
!   [(set_attr "op_type" "RS")
     (set_attr "atype"   "mem")])

! (define_insn "*cmpsi_ccs_0"
    [(set (reg 33)
!         (compare (match_operand:SI 0 "register_operand" "d")
!                  (match_operand:SI 1 "const0_operand" "")))]
!   "s390_match_ccmode(insn, CCSmode)"
!   "ltr\\t%0,%0"
!   [(set_attr "op_type" "RR")])

! (define_insn "*cmpsidi_ccs"
    [(set (reg 33)
!         (compare (match_operand:SI 0 "register_operand" "d")
!                  (sign_extend:SI (match_operand:HI 1 "memory_operand"
"m"))))]
!   "s390_match_ccmode(insn, CCSmode)"
!   "ch\\t%0,%1"
!   [(set_attr "op_type" "RR")
!    (set_attr "atype"   "mem")])

! (define_insn "*cmpsi_ccs"
    [(set (reg 33)
!         (compare (match_operand:SI 0 "register_operand" "d,d,d")
!                  (match_operand:SI 1 "general_operand" "d,K,m")))]
!   "s390_match_ccmode(insn, CCSmode)"
!   "@
!    cr\\t%0,%1
!    chi\\t%0,%c1
!    c\\t%0,%1"
!   [(set_attr "op_type" "RR,RI,RX")
!    (set_attr "atype"   "reg,reg,mem")])
!
! (define_insn "*cmpsi_ccu"
    [(set (reg 33)
!         (compare (match_operand:SI 0 "register_operand" "d,d")
!                  (match_operand:SI 1 "general_operand" "d,m")))]
!   "s390_match_ccmode(insn, CCUmode)"
!   "@
!    clr\\t%0,%1
!    cl\\t%0,%1"
!   [(set_attr "op_type" "RR,RX")
!    (set_attr "atype"   "reg,mem")])

! (define_insn "*cmpsi_ccu_mem"
    [(set (reg 33)
!         (compare (match_operand:SI 0 "s_operand" "oQ")
!                  (match_operand:SI 1 "s_imm_operand" "oQ")))]
!   "s390_match_ccmode(insn, CCUmode)"
!   "clc\\t%O0(4,%R0),%1"
!    [(set_attr "op_type" "SS")
!     (set_attr "atype"   "mem")])


! ; HI instructions

! (define_insn "*cmphi_tm_sub"
    [(set (reg 33)
!         (compare (and:SI (subreg:SI (match_operand:HI 0 "s_operand"
"%Qo") 0)
!                          (match_operand:SI 1 "immediate_operand" "n"))
!                  (const_int 0)))]
!   "s390_match_ccmode(insn, CCTmode)
!    && s390_single_qi (operands[1], HImode, 0) >= 0"
!   "*
! {
!   int part = s390_single_qi (operands[1], HImode, 0);
!   operands[1] = GEN_INT (s390_extract_qi (operands[1], HImode, part));

!   operands[0] = gen_rtx_MEM (QImode,
!                      plus_constant (XEXP (operands[0], 0), part));
!   return \"tm\\t%0,%b1\";
! }"
!   [(set_attr "op_type" "SI")
!    (set_attr "atype"   "mem")])

! (define_insn "*icm3"
    [(set (reg 33)
          (compare (match_operand:HI 0 "s_operand" "Qo")
                   (match_operand:HI 1 "const0_operand" "")))
--- 382,506 ----
    [(set_attr "op_type" "SI")
     (set_attr "atype"   "mem")])

! (define_insn "*tmhi_mem"
    [(set (reg 33)
!         (compare (and:SI (subreg:SI (match_operand:HI 0 "s_operand"
"%Qo") 0)
!                          (match_operand:SI 1 "immediate_operand" "n"))
!                  (match_operand:SI 2 "immediate_operand" "n")))]
!   "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))
!    && s390_single_qi (operands[1], HImode, 0) >= 0"
!   "*
! {
!   int part = s390_single_qi (operands[1], HImode, 0);
!   operands[1] = GEN_INT (s390_extract_qi (operands[1], HImode, part));

!   operands[0] = gen_rtx_MEM (QImode,
!                      plus_constant (XEXP (operands[0], 0), part));
!   return \"tm\\t%0,%b1\";
! }"
!   [(set_attr "op_type" "SI")
     (set_attr "atype"   "mem")])

! (define_insn "*tmqi_mem"
    [(set (reg 33)
!         (compare (and:SI (subreg:SI (match_operand:QI 0 "s_operand"
"%Qo") 0)
!                          (match_operand:SI 1 "immediate_operand" "n"))
!                  (match_operand:SI 2 "immediate_operand" "n")))]
!   "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2],
0))"
!   "tm\\t%0,%b1"
!   [(set_attr "op_type" "SI")
     (set_attr "atype"   "mem")])

! (define_insn "*tmhi_full"
    [(set (reg 33)
!         (compare (match_operand:HI 0 "register_operand" "d")
!                  (match_operand:HI 1 "immediate_operand" "n")))]
!   "s390_match_ccmode (insn, s390_tm_ccmode (GEN_INT (-1), operands[1],
1))"
!   "tml\\t%0,65535"
!   [(set_attr "op_type" "RX")])

! (define_insn "*tmqi_full"
    [(set (reg 33)
!         (compare (match_operand:QI 0 "register_operand" "d")
!                  (match_operand:QI 1 "immediate_operand" "n")))]
!   "s390_match_ccmode (insn, s390_tm_ccmode (GEN_INT (-1), operands[1],
1))"
!   "tml\\t%0,255"
!   [(set_attr "op_type" "RI")])

!
! ; Load-and-Test instructions
!
! (define_insn "*tstdi_sign"
    [(set (reg 33)
!         (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")
!         (sign_extend:DI (match_dup 0)))]
!   "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
!   "ltgfr\\t%2,%0"
!   [(set_attr "op_type" "RRE")])
!
! (define_insn "*tstdi"
    [(set (reg 33)
!         (compare (match_operand:DI 0 "register_operand" "d")
!                  (match_operand:DI 1 "const0_operand" "")))
!    (set (match_operand:DI 2 "register_operand" "=d")
!         (match_dup 0))]
!   "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
!   "ltgr\\t%2,%0"
!   [(set_attr "op_type" "RRE")])

! (define_insn "*tstdi_cconly"
    [(set (reg 33)
!         (compare (match_operand:DI 0 "register_operand" "d")
!                  (match_operand:DI 1 "const0_operand" "")))]
!   "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
!   "ltgr\\t%0,%0"
!   [(set_attr "op_type" "RRE")])

+ (define_insn "*tstdi_cconly_31"
+   [(set (reg 33)
+         (compare (match_operand:DI 0 "register_operand" "d")
+                  (match_operand:DI 1 "const0_operand" "")))]
+   "s390_match_ccmode(insn, CCSmode) && !TARGET_64BIT"
+   "srda\\t%0,0"
+   [(set_attr "op_type" "RS")])

! (define_insn "*tstsi"
!   [(set (reg 33)
!         (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q")
!                  (match_operand:SI 1 "const0_operand" "")))
!    (set (match_operand:SI 2 "register_operand" "=d,d")
!         (match_dup 0))]
!   "s390_match_ccmode(insn, CCSmode)"
!   "@
!    ltr\\t%2,%0
!    icm\\t%2,15,%0"
!   [(set_attr "op_type" "RR,RS")
!    (set_attr "atype"   "reg,mem")])

! (define_insn "*tstsi_cconly"
    [(set (reg 33)
!         (compare (match_operand:SI 0 "nonimmediate_operand" "d,Q")
!                  (match_operand:SI 1 "const0_operand" "")))
!    (clobber (match_scratch:SI 2 "=X,d"))]
!   "s390_match_ccmode(insn, CCSmode)"
!   "@
!    ltr\\t%0,%0
!    icm\\t%2,15,%0"
!   [(set_attr "op_type" "RR,RS")
!    (set_attr "atype"   "reg,mem")])

! (define_insn "*tstsi_cconly2"
!   [(set (reg 33)
!         (compare (match_operand:SI 0 "register_operand" "d")
!                  (match_operand:SI 1 "const0_operand" "")))]
!   "s390_match_ccmode(insn, CCSmode)"
!   "ltr\\t%0,%0"
!   [(set_attr "op_type" "RR")])

! (define_insn "*tsthi"
    [(set (reg 33)
          (compare (match_operand:HI 0 "s_operand" "Qo")
                   (match_operand:HI 1 "const0_operand" "")))
***************
*** 555,569 ****
    [(set_attr "op_type" "RS")
     (set_attr "atype"   "mem")])

! (define_insn "*cmphi_cct_0"
!   [(set (reg 33)
!         (compare (match_operand:HI 0 "register_operand" "d")
!                  (match_operand:HI 1 "const0_operand"   "")))]
!   "s390_match_ccmode(insn, CCTmode)"
!   "tml\\t%0,65535"
!   [(set_attr "op_type" "RX")])
!
! (define_insn "*cmphi_ccs_0"
    [(set (reg 33)
          (compare (match_operand:HI 0 "s_operand" "Qo")
                   (match_operand:HI 1 "const0_operand" "")))
--- 511,517 ----
    [(set_attr "op_type" "RS")
     (set_attr "atype"   "mem")])

! (define_insn "*tsthi_cconly"
    [(set (reg 33)
          (compare (match_operand:HI 0 "s_operand" "Qo")
                   (match_operand:HI 1 "const0_operand" "")))
***************
*** 573,688 ****
    [(set_attr "op_type" "RS")
     (set_attr "atype"   "mem")])

! (define_insn "*cmphi_ccu"
    [(set (reg 33)
!         (compare (match_operand:HI 0 "register_operand" "d")
!                  (match_operand:HI 1 "s_imm_operand" "Qo")))]
!   "s390_match_ccmode(insn, CCUmode)"
!   "clm\\t%0,3,%1"
    [(set_attr "op_type" "RS")
     (set_attr "atype"   "mem")])

! (define_insn "*cmphi_ccu_mem"
    [(set (reg 33)
!         (compare (match_operand:HI 0 "s_operand" "oQ")
!                  (match_operand:HI 1 "s_imm_operand" "oQ")))]
!   "s390_match_ccmode(insn, CCUmode)"
!   "clc\\t%O0(2,%R0),%1"
!   [(set_attr "op_type" "SS")
     (set_attr "atype"   "mem")])


! ; QI instructions
!
! (define_insn "*cmpqi_tm2"
!   [(set (reg 33)
!         (compare (zero_extract:SI (match_operand:QI 0 "s_operand" "Qo")
!                               (match_operand:SI 1 "const_int_operand"
"n")
!                                   (match_operand:SI 2 "const_int_operand"
"n"))
!                  (const_int 0)))]
!   "s390_match_ccmode(insn, CCTmode)
!    && INTVAL (operands[1]) >= 1 && INTVAL (operands[2]) >= 0
!    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 8"
!   "*
! {
!   int block = (1 << INTVAL (operands[1])) - 1;
!   int shift = 8 - INTVAL (operands[1]) - INTVAL (operands[2]);
!
!   operands[2] = GEN_INT (block << shift);
!   return \"tm\\t%0,%b2\";
! }"
!   [(set_attr "op_type" "SI")
!    (set_attr "atype"   "mem")])

! (define_insn "*cmpqi_tm"
    [(set (reg 33)
!         (compare (and:QI (match_operand:QI 0 "nonimmediate_operand"
"%d,Q")
!                          (match_operand:QI 1 "immediate_operand" "n,n"))
!                  (const_int 0)))]
!   "s390_match_ccmode(insn, CCTmode)"
    "@
!    tml\\t%0,%b1
!    tm\\t%0,%b1"
!   [(set_attr "op_type" "RI,SI")
     (set_attr "atype"   "reg,mem")])

! (define_insn "*cmpqi_tm_sub"
    [(set (reg 33)
!         (compare (and:SI (subreg:SI (match_operand:QI 0 "s_operand"
"%Qo") 0)
!                          (match_operand:SI 1 "immediate_operand" "n"))
!                  (const_int 0)))]
!   "s390_match_ccmode(insn, CCTmode)"
!   "tm\\t%0,%b1"
!   [(set_attr "op_type" "SI")
     (set_attr "atype"   "mem")])

! (define_insn "*icm1"
    [(set (reg 33)
!         (compare (match_operand:QI 0 "s_operand" "Qo")
!                  (match_operand:QI 1 "const0_operand" "")))
!    (set (match_operand:QI 2 "register_operand" "=d")
!         (match_dup 0))]
    "s390_match_ccmode(insn, CCSmode)"
!   "icm\\t%2,1,%0"
!   [(set_attr "op_type" "RS")
!    (set_attr "atype"   "mem")])

! (define_insn "*tm_0"
    [(set (reg 33)
!         (compare (zero_extend:SI (and:QI (match_operand:QI 0 "s_operand"
"Qo")
!                                          (match_operand:QI 1
"immediate_operand" "")))
!                  (const_int 0)))]
!   "s390_match_ccmode(insn, CCTmode) &&
!    INTVAL(operands[1]) >= 0 && INTVAL(operands[1]) < 256"
!   "tm\\t%0,%1"
!   [(set_attr "op_type" "RI")
!    (set_attr "atype"   "mem")])

! (define_insn "*cmpqi_cct_0"
    [(set (reg 33)
!         (compare (match_operand:QI 0 "register_operand" "d")
!                  (match_operand:QI 1 "const0_operand"   "")))]
!   "s390_match_ccmode(insn, CCTmode)"
!   "tml\\t%0,255"
!   [(set_attr "op_type" "RI")])

! (define_insn "*cmpqi_ccs_0"
    [(set (reg 33)
!         (compare (match_operand:QI 0 "s_operand" "Qo")
!                  (match_operand:QI 1 "const0_operand" "")))
!    (clobber (match_scratch:QI 2 "=d"))]
!   "s390_match_ccmode(insn, CCSmode)"
!   "icm\\t%2,1,%0"
!   [(set_attr "op_type" "RS")
!    (set_attr "atype"   "mem")])

! (define_insn "*cmpqi_ccu_0"
    [(set (reg 33)
!         (compare (match_operand:QI 0 "s_operand"      "Qo")
!                  (match_operand:QI 1 "const0_operand" "")))]
    "s390_match_ccmode(insn, CCUmode)"
!   "cli\\t%0,0"
!   [(set_attr "op_type" "SI")
     (set_attr "atype"   "mem")])

  (define_insn "*cmpqi_ccu"
--- 521,637 ----
    [(set_attr "op_type" "RS")
     (set_attr "atype"   "mem")])

! (define_insn "*tstqi"
    [(set (reg 33)
!         (compare (match_operand:QI 0 "s_operand" "Qo")
!                  (match_operand:QI 1 "const0_operand" "")))
!    (set (match_operand:QI 2 "register_operand" "=d")
!         (match_dup 0))]
!   "s390_match_ccmode(insn, CCSmode)"
!   "icm\\t%2,1,%0"
    [(set_attr "op_type" "RS")
     (set_attr "atype"   "mem")])

! (define_insn "*tstqi_cconly"
    [(set (reg 33)
!         (compare (match_operand:QI 0 "s_operand" "Qo")
!                  (match_operand:QI 1 "const0_operand" "")))
!    (clobber (match_scratch:QI 2 "=d"))]
!   "s390_match_ccmode(insn, CCSmode)"
!   "icm\\t%2,1,%0"
!   [(set_attr "op_type" "RS")
     (set_attr "atype"   "mem")])


! ; Compare (signed) instructions

! (define_insn "*cmpdi_ccs_sign"
    [(set (reg 33)
!         (compare (sign_extend:DI (match_operand:SI 1
"nonimmediate_operand" "d,m"))
!                  (match_operand:DI 0 "register_operand" "d,d")))]
!   "s390_match_ccmode(insn, CCSRmode) && TARGET_64BIT"
    "@
!    cgfr\\t%0,%1
!    cgf\\t%0,%1"
!   [(set_attr "op_type" "RRE,RXE")
     (set_attr "atype"   "reg,mem")])

! (define_insn "*cmpdi_ccs"
    [(set (reg 33)
!         (compare (match_operand:DI 0 "register_operand" "d,d,d")
!                  (match_operand:DI 1 "general_operand" "d,K,m")))]
!   "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT"
!   "@
!    cgr\\t%0,%1
!    cghi\\t%0,%c1
!    cg\\t%0,%1"
!   [(set_attr "op_type" "RRE,RI,RXE")
!    (set_attr "atype"    "reg,reg,mem")])
!
! (define_insn "*cmpsi_ccs_sign"
!   [(set (reg 33)
!         (compare (sign_extend:SI (match_operand:HI 1 "memory_operand"
"m"))
!                  (match_operand:SI 0 "register_operand" "d")))]
!   "s390_match_ccmode(insn, CCSRmode)"
!   "ch\\t%0,%1"
!   [(set_attr "op_type" "RX")
     (set_attr "atype"   "mem")])

! (define_insn "*cmpsi_ccs"
    [(set (reg 33)
!         (compare (match_operand:SI 0 "register_operand" "d,d,d")
!                  (match_operand:SI 1 "general_operand" "d,K,m")))]
    "s390_match_ccmode(insn, CCSmode)"
!   "@
!    cr\\t%0,%1
!    chi\\t%0,%c1
!    c\\t%0,%1"
!   [(set_attr "op_type" "RR,RI,RX")
!    (set_attr "atype"   "reg,reg,mem")])
!

! ; Compare (unsigned) instructions
!
! (define_insn "*cmpdi_ccu_zero"
    [(set (reg 33)
!         (compare (zero_extend:DI (match_operand:SI 1
"nonimmediate_operand" "d,m"))
!                  (match_operand:DI 0 "register_operand" "d,d")))]
!   "s390_match_ccmode(insn, CCURmode) && TARGET_64BIT"
!   "@
!    clgfr\\t%0,%1
!    clgf\\t%0,%1"
!   [(set_attr "op_type" "RRE,RXE")
!    (set_attr "atype"   "reg,mem")])

! (define_insn "*cmpdi_ccu"
    [(set (reg 33)
!         (compare (match_operand:DI 0 "register_operand" "d,d")
!                  (match_operand:DI 1 "general_operand" "d,m")))]
!   "s390_match_ccmode(insn, CCUmode) && TARGET_64BIT"
!   "@
!    clgr\\t%0,%1
!    clg\\t%0,%1"
!   [(set_attr "op_type" "RRE,RXE")
!    (set_attr "atype"   "reg,mem")])

! (define_insn "*cmpsi_ccu"
    [(set (reg 33)
!         (compare (match_operand:SI 0 "register_operand" "d,d")
!                  (match_operand:SI 1 "general_operand" "d,m")))]
!   "s390_match_ccmode(insn, CCUmode)"
!   "@
!    clr\\t%0,%1
!    cl\\t%0,%1"
!   [(set_attr "op_type" "RR,RX")
!    (set_attr "atype"   "reg,mem")])

! (define_insn "*cmphi_ccu"
    [(set (reg 33)
!         (compare (match_operand:HI 0 "register_operand" "d")
!                  (match_operand:HI 1 "s_imm_operand" "Qo")))]
    "s390_match_ccmode(insn, CCUmode)"
!   "clm\\t%0,3,%1"
!   [(set_attr "op_type" "RS")
     (set_attr "atype"   "mem")])

  (define_insn "*cmpqi_ccu"
***************
*** 694,709 ****
    [(set_attr "op_type" "RS")
     (set_attr "atype"   "mem")])

! (define_insn "*cmpqi_ccu_immed"
    [(set (reg 33)
          (compare (match_operand:QI 0 "s_operand" "Qo")
!                  (match_operand:QI 1 "const_int_operand" "n")))]
!   "s390_match_ccmode(insn, CCUmode) &&
!    INTVAL(operands[1]) >= 0 && INTVAL(operands[1]) < 256"
!   "cli\\t%0,%1"
    [(set_attr "op_type" "SI")
     (set_attr "atype"   "mem")])

  (define_insn "*cmpqi_ccu_mem"
    [(set (reg 33)
          (compare (match_operand:QI 0 "s_operand" "oQ")
--- 643,684 ----
    [(set_attr "op_type" "RS")
     (set_attr "atype"   "mem")])

! (define_insn "*cli"
    [(set (reg 33)
          (compare (match_operand:QI 0 "s_operand" "Qo")
!                  (match_operand:QI 1 "immediate_operand" "n")))]
!   "s390_match_ccmode (insn, CCUmode)"
!   "cli\\t%0,%b1"
    [(set_attr "op_type" "SI")
     (set_attr "atype"   "mem")])

+ (define_insn "*cmpdi_ccu_mem"
+   [(set (reg 33)
+         (compare (match_operand:DI 0 "s_operand" "oQ")
+                  (match_operand:DI 1 "s_imm_operand" "oQ")))]
+   "s390_match_ccmode(insn, CCUmode)"
+   "clc\\t%O0(8,%R0),%1"
+   [(set_attr "op_type" "SS")
+    (set_attr "atype"   "mem")])
+
+ (define_insn "*cmpsi_ccu_mem"
+   [(set (reg 33)
+         (compare (match_operand:SI 0 "s_operand" "oQ")
+                  (match_operand:SI 1 "s_imm_operand" "oQ")))]
+   "s390_match_ccmode(insn, CCUmode)"
+   "clc\\t%O0(4,%R0),%1"
+    [(set_attr "op_type" "SS")
+     (set_attr "atype"   "mem")])
+
+ (define_insn "*cmphi_ccu_mem"
+   [(set (reg 33)
+         (compare (match_operand:HI 0 "s_operand" "oQ")
+                  (match_operand:HI 1 "s_imm_operand" "oQ")))]
+   "s390_match_ccmode(insn, CCUmode)"
+   "clc\\t%O0(2,%R0),%1"
+   [(set_attr "op_type" "SS")
+    (set_attr "atype"   "mem")])
+
  (define_insn "*cmpqi_ccu_mem"
    [(set (reg 33)
          (compare (match_operand:QI 0 "s_operand" "oQ")
***************
*** 3061,3090 ****
  ;  because of unpredictable Bits in Register for Halfword and Byte
  ;  the ConditionCode can be set wrong in operations for Halfword and Byte

! ;;
! ;;- Add instructions.
! ;;

! ;
! ; adddi3 instruction pattern(s).
! ;

! (define_insn "addaddr_esame"
!   [(set (match_operand:DI 0 "register_operand" "=a,a")
!         (plus:DI (match_operand:DI 1 "register_operand" "%a,a")
!                  (match_operand:DI 2 "nonmemory_operand" "J,a")))]
!   "TARGET_64BIT && (((REGNO (operands[1]) == STACK_POINTER_REGNUM ) ||
!      (REGNO (operands[1]) == BASE_REGISTER)) &&
!     (GET_CODE (operands[2]) == REG ||
!      CONST_OK_FOR_LETTER_P (INTVAL (operands[2]),'J')))"
    "@
!    la\\t%0,%c2(,%1)
!    la\\t%0,0(%1,%2)"
!   [(set_attr "op_type" "RX")
!    (set_attr "atype"   "mem")
!    (set_attr "type"    "la")])

! (define_insn "adddi3_64"
    [(set (match_operand:DI 0 "register_operand" "=d,d,d")
          (plus:DI (match_operand:DI 1 "register_operand" "%0,0,0")
                   (match_operand:DI 2 "general_operand" "d,K,m") ) )
--- 3036,3155 ----
  ;  because of unpredictable Bits in Register for Halfword and Byte
  ;  the ConditionCode can be set wrong in operations for Halfword and Byte

! ;;
! ;;- Add instructions.
! ;;
!
! ;
! ; adddi3 instruction pattern(s).
! ;
!
! (define_insn "addaddr_esame"
!   [(set (match_operand:DI 0 "register_operand" "=a,a")
!         (plus:DI (match_operand:DI 1 "register_operand" "%a,a")
!                  (match_operand:DI 2 "nonmemory_operand" "J,a")))]
!   "TARGET_64BIT && (((REGNO (operands[1]) == STACK_POINTER_REGNUM ) ||
!      (REGNO (operands[1]) == BASE_REGISTER)) &&
!     (GET_CODE (operands[2]) == REG ||
!      CONST_OK_FOR_LETTER_P (INTVAL (operands[2]),'J')))"
!   "@
!    la\\t%0,%c2(,%1)
!    la\\t%0,0(%1,%2)"
!   [(set_attr "op_type" "RX")
!    (set_attr "atype"   "mem")
!    (set_attr "type"    "la")])
!
! (define_insn "*adddi3_sign"
!   [(set (match_operand:DI 0 "register_operand" "=d,d")
!         (plus:DI (sign_extend:DI (match_operand:SI 2 "general_operand"
"d,m"))
!                  (match_operand:DI 1 "register_operand" "0,0")))
!    (clobber (reg:CC 33))]
!   "TARGET_64BIT"
!   "@
!    agfr\\t%0,%2
!    agf\\t%0,%2"
!   [(set_attr "op_type"  "RRE,RXE")
!    (set_attr "atype"    "reg,mem")])
!
! (define_insn "*adddi3_zero_cc"
!   [(set (reg 33)
!         (compare (plus:DI (zero_extend:DI (match_operand:SI 2
"general_operand" "d,m"))
!                           (match_operand:DI 1 "register_operand" "0,0"))
!                  (const_int 0)))
!    (set (match_operand:DI 0 "register_operand" "=d,d")
!         (plus:DI (zero_extend:DI (match_dup 2)) (match_dup 1)))]
!   "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
!   "@
!    algfr\\t%0,%2
!    algf\\t%0,%2"
!   [(set_attr "op_type"  "RRE,RXE")
!    (set_attr "atype"    "reg,mem")])
!
! (define_insn "*adddi3_zero_cconly"
!   [(set (reg 33)
!         (compare (plus:DI (zero_extend:DI (match_operand:SI 2
"general_operand" "d,m"))
!                           (match_operand:DI 1 "register_operand" "0,0"))
!                  (const_int 0)))
!    (clobber (match_scratch:DI 0 "=d,d"))]
!   "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
!   "@
!    algfr\\t%0,%2
!    algf\\t%0,%2"
!   [(set_attr "op_type"  "RRE,RXE")
!    (set_attr "atype"    "reg,mem")])
!
! (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"))
!                  (match_operand:DI 1 "register_operand" "0,0")))
!    (clobber (reg:CC 33))]
!   "TARGET_64BIT"
!   "@
!    algfr\\t%0,%2
!    algf\\t%0,%2"
!   [(set_attr "op_type"  "RRE,RXE")
!    (set_attr "atype"    "reg,mem")])
!
! (define_insn "*adddi3_cc"
!   [(set (reg 33)
!         (compare (plus:DI (match_operand:DI 1 "register_operand" "%0,0")
!                           (match_operand:DI 2 "general_operand" "d,m"))
!                  (const_int 0)))
!    (set (match_operand:DI 0 "register_operand" "=d,d")
!         (plus:DI (match_dup 1) (match_dup 2)))]
!   "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
!   "@
!    algr\\t%0,%2
!    alg\\t%0,%2"
!   [(set_attr "op_type"  "RRE,RXE")
!    (set_attr "atype"    "reg,mem")])

! (define_insn "*adddi3_cconly"
!   [(set (reg 33)
!         (compare (plus:DI (match_operand:DI 1 "register_operand" "%0,0")
!                           (match_operand:DI 2 "general_operand" "d,m"))
!                  (const_int 0)))
!    (clobber (match_scratch:DI 0 "=d,d"))]
!   "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
!   "@
!    algr\\t%0,%2
!    alg\\t%0,%2"
!   [(set_attr "op_type"  "RRE,RXE")
!    (set_attr "atype"    "reg,mem")])

! (define_insn "*adddi3_cconly2"
!   [(set (reg 33)
!         (compare (match_operand:DI 1 "register_operand" "%0,0")
!                  (neg:SI (match_operand:DI 2 "general_operand" "d,m"))))
!    (clobber (match_scratch:DI 0 "=d,d"))]
!   "s390_match_ccmode(insn, CCLmode) && TARGET_64BIT"
    "@
!    algr\\t%0,%2
!    alg\\t%0,%2"
!   [(set_attr "op_type"  "RRE,RXE")
!    (set_attr "atype"    "reg,mem")])

! (define_insn "*adddi3_64"
    [(set (match_operand:DI 0 "register_operand" "=d,d,d")
          (plus:DI (match_operand:DI 1 "register_operand" "%0,0,0")
                   (match_operand:DI 2 "general_operand" "d,K,m") ) )
***************
*** 3097,3147 ****
    [(set_attr "op_type"  "RRE,RI,RXE")
     (set_attr "atype"    "reg,reg,mem")])

! (define_insn "adddi3_31"
!   [(set (match_operand:DI 0 "register_operand" "=d,d")
!         (plus:DI (match_operand:DI 1 "register_operand" "0,0")
!                  (match_operand:DI 2 "general_operand" "d,m") ) )
     (clobber (reg:CC 33))]
    "!TARGET_64BIT"
!   "*
! {
!    switch (which_alternative)
!      {
!      case 0: /* d <- d */
!        output_asm_insn (\"ar\\t%0,%2\", operands);
!        output_asm_insn (\"alr\\t%N0,%N2\", operands);
!        break;
!
!      case 1: /* d <- m */
!        output_asm_insn (\"a\\t%0,%2\", operands);
!        output_asm_insn (\"al\\t%N0,%N2\", operands);
!        break;
!
!      default:
!        abort ();
!      }
!
!    output_asm_insn (\"brc\\t12,.+8\", operands);
!    return \"ahi\\t%0,1\";
! }"
!   [(set_attr "op_type" "NN,NN")
!    (set_attr "atype"   "reg,mem")
!    (set_attr "type"    "o2,o2")
!    (set_attr "length"  "12,16")])

  (define_expand "adddi3"
!   [(set (match_operand:DI 0 "register_operand" "")
!         (plus:DI (match_operand:DI 1 "register_operand" "")
!                  (match_operand:DI 2 "general_operand" "")))]
    ""
!   "
! {
!   if (TARGET_64BIT)
!     emit_insn(gen_adddi3_64 (operands[0],operands[1],operands[2]));
!   else
!     emit_insn(gen_adddi3_31 (operands[0],operands[1],operands[2]));
!   DONE;
! }")

  (define_insn "*la_64"
    [(set (match_operand:DI 0 "register_operand" "=d")
--- 3162,3209 ----
    [(set_attr "op_type"  "RRE,RI,RXE")
     (set_attr "atype"    "reg,reg,mem")])

! (define_insn_and_split "*adddi3_31"
!   [(set (match_operand:DI 0 "register_operand" "=&d")
!         (plus:DI (match_operand:DI 1 "register_operand" "%0")
!                  (match_operand:DI 2 "general_operand" "dm") ) )
     (clobber (reg:CC 33))]
    "!TARGET_64BIT"
!   "#"
!   "&& reload_completed"
!   [(parallel
!     [(set (match_dup 3) (plus:SI (match_dup 4) (match_dup 5)))
!      (clobber (reg:CC 33))])
!    (parallel
!     [(set (reg:CCL1 33)
!           (compare:CCL1 (plus:SI (match_dup 7) (match_dup 8))
!                         (match_dup 7)))
!      (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
!    (set (pc)
!         (if_then_else (ltu (reg:CCL1 33) (const_int 0))
!                       (pc)
!                       (label_ref (match_dup 9))))
!    (parallel
!     [(set (match_dup 3) (plus:SI (match_dup 3) (const_int 1)))
!      (clobber (reg:CC 33))])
!    (match_dup 9)]
!   "operands[3] = operand_subword (operands[0], 0, 1, DImode);
!    operands[4] = operand_subword (operands[1], 0, 1, DImode);
!    operands[5] = operand_subword (operands[2], 0, 1, DImode);
!    operands[6] = operand_subword (operands[0], 1, 1, DImode);
!    operands[7] = operand_subword (operands[1], 1, 1, DImode);
!    operands[8] = operand_subword (operands[2], 1, 1, DImode);
!    operands[9] = gen_label_rtx ();"
!   [(set_attr "op_type"  "NN")
!    (set_attr "type"     "o3")])

  (define_expand "adddi3"
!   [(parallel
!     [(set (match_operand:DI 0 "register_operand" "")
!           (plus:DI (match_operand:DI 1 "register_operand" "")
!                    (match_operand:DI 2 "general_operand" "")))
!      (clobber (reg:CC 33))])]
    ""
!   "")

  (define_insn "*la_64"
    [(set (match_operand:DI 0 "register_operand" "=d")
***************
*** 3178,3191 ****
      (set_attr "atype"    "mem")
      (set_attr "type"     "la")])

  (define_insn "*addsi3_cc"
    [(set (reg 33)
          (compare (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
!                           (match_operand:SI 2 "nonimmediate_operand"
"d,m"))
                   (const_int 0)))
     (set (match_operand:SI 0 "register_operand" "=d,d")
          (plus:SI (match_dup 1) (match_dup 2)))]
!   "s390_match_ccmode(insn, CCLmode)"
    "@
     alr\\t%0,%2
     al\\t%0,%2"
--- 3240,3307 ----
      (set_attr "atype"    "mem")
      (set_attr "type"     "la")])

+ (define_insn "*addsi3_carry1_cc"
+   [(set (reg 33)
+         (compare (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
+                           (match_operand:SI 2 "general_operand" "d,m"))
+                  (match_dup 1)))
+    (set (match_operand:SI 0 "register_operand" "=d,d")
+         (plus:SI (match_dup 1) (match_dup 2)))]
+   "s390_match_ccmode (insn, CCL1mode)"
+   "@
+    alr\\t%0,%2
+    al\\t%0,%2"
+   [(set_attr "op_type"  "RR,RX")
+    (set_attr "atype"    "reg,mem")])
+
+ (define_insn "*addsi3_carry1_cconly"
+   [(set (reg 33)
+         (compare (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
+                           (match_operand:SI 2 "general_operand" "d,m"))
+                  (match_dup 1)))
+    (clobber (match_scratch:SI 0 "=d,d"))]
+   "s390_match_ccmode (insn, CCL1mode)"
+   "@
+    alr\\t%0,%2
+    al\\t%0,%2"
+   [(set_attr "op_type"  "RR,RX")
+    (set_attr "atype"    "reg,mem")])
+
+ (define_insn "*addsi3_carry2_cc"
+   [(set (reg 33)
+         (compare (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
+                           (match_operand:SI 2 "general_operand" "d,m"))
+                  (match_dup 2)))
+    (set (match_operand:SI 0 "register_operand" "=d,d")
+         (plus:SI (match_dup 1) (match_dup 2)))]
+   "s390_match_ccmode (insn, CCL1mode)"
+   "@
+    alr\\t%0,%2
+    al\\t%0,%2"
+   [(set_attr "op_type"  "RR,RX")
+    (set_attr "atype"    "reg,mem")])
+
+ (define_insn "*addsi3_carry2_cconly"
+   [(set (reg 33)
+         (compare (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
+                           (match_operand:SI 2 "general_operand" "d,m"))
+                  (match_dup 2)))
+    (clobber (match_scratch:SI 0 "=d,d"))]
+   "s390_match_ccmode (insn, CCL1mode)"
+   "@
+    alr\\t%0,%2
+    al\\t%0,%2"
+   [(set_attr "op_type"  "RR,RX")
+    (set_attr "atype"    "reg,mem")])
+
  (define_insn "*addsi3_cc"
    [(set (reg 33)
          (compare (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
!                           (match_operand:SI 2 "general_operand" "d,m"))
                   (const_int 0)))
     (set (match_operand:SI 0 "register_operand" "=d,d")
          (plus:SI (match_dup 1) (match_dup 2)))]
!   "s390_match_ccmode (insn, CCLmode)"
    "@
     alr\\t%0,%2
     al\\t%0,%2"
***************
*** 3198,3204 ****
                            (match_operand:SI 2 "general_operand" "d,m"))
                   (const_int 0)))
     (clobber (match_scratch:SI 0 "=d,d"))]
!   "s390_match_ccmode(insn, CCLmode)"
    "@
     alr\\t%0,%2
     al\\t%0,%2"
--- 3314,3320 ----
                            (match_operand:SI 2 "general_operand" "d,m"))
                   (const_int 0)))
     (clobber (match_scratch:SI 0 "=d,d"))]
!   "s390_match_ccmode (insn, CCLmode)"
    "@
     alr\\t%0,%2
     al\\t%0,%2"
***************
*** 3217,3222 ****
--- 3333,3358 ----
    [(set_attr "op_type"  "RR,RX")
     (set_attr "atype"    "reg,mem")])

+ (define_insn "*addsi3_sign"
+   [(set (match_operand:SI 0 "register_operand" "=d")
+         (plus:SI (match_operand:SI 1 "register_operand" "0")
+                  (sign_extend:SI (match_operand:HI 2 "memory_operand"
"m"))))
+    (clobber (reg:CC 33))]
+   ""
+   "ah\\t%0,%2"
+   [(set_attr "op_type"  "RX")
+    (set_attr "atype"    "mem")])
+
+ (define_insn "*addsi3_sub"
+   [(set (match_operand:SI 0 "register_operand" "=d")
+         (plus:SI (match_operand:SI 1 "register_operand" "0")
+                  (subreg:SI (match_operand:HI 2 "memory_operand" "m")
0)))
+    (clobber (reg:CC 33))]
+   ""
+   "ah\\t%0,%2"
+   [(set_attr "op_type"  "RX")
+    (set_attr "atype"    "mem")])
+
  (define_insn "addsi3"
    [(set (match_operand:SI 0 "register_operand" "=d,d,d")
          (plus:SI (match_operand:SI 1 "register_operand" "%0,0,0")
***************
*** 3252,3292 ****


  ;
- ; addhi3 instruction pattern(s).
- ;
-
- (define_insn "addhi3"
-   [(set (match_operand:HI 0 "register_operand" "=d,d,d")
-         (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0")
-                  (match_operand:HI 2 "general_operand" "d,K,m")))
-    (clobber (reg:CC 33))]
-   ""
-   "@
-    ar\\t%0,%2
-    ahi\\t%0,%h2
-    ah\\t%0,%2"
-   [(set_attr "op_type"  "RR,RI,RX")
-    (set_attr "atype"    "reg,reg,mem")])
-
-
- ;
- ; addqi3 instruction pattern(s).
- ;
-
- (define_insn "addqi3"
-   [(set (match_operand:QI 0 "register_operand" "=d,d")
-         (plus:QI (match_operand:QI 1 "register_operand" "%0,0")
-                  (match_operand:QI 2 "general_operand" "a,n")))
-    (clobber (reg:CC 33))]
-   ""
-   "@
-    ar\\t%0,%2
-    ahi\\t%0,%h2"
-   [(set_attr "op_type"  "RX,RX")
-    (set_attr "atype"    "reg,mem")])
-
-
- ;
  ; adddf3 instruction pattern(s).
  ;

--- 3388,3393 ----
***************
*** 3369,3374 ****
--- 3470,3553 ----
  ; subdi3 instruction pattern(s).
  ;

+ (define_insn "*subdi3_sign"
+   [(set (match_operand:DI 0 "register_operand" "=d,d")
+         (minus:DI (match_operand:DI 1 "register_operand" "0,0")
+                   (sign_extend:DI (match_operand:SI 2 "general_operand"
"d,m"))))
+    (clobber (reg:CC 33))]
+   "TARGET_64BIT"
+   "@
+    sgfr\\t%0,%2
+    sgf\\t%0,%2"
+   [(set_attr "op_type"  "RRE,RXE")
+    (set_attr "atype"    "reg,mem")])
+
+ (define_insn "*subdi3_zero_cc"
+   [(set (reg 33)
+         (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
+                            (zero_extend:DI (match_operand:SI 2
"general_operand" "d,m")))
+                  (const_int 0)))
+    (set (match_operand:DI 0 "register_operand" "=d,d")
+         (minus:DI (match_dup 1) (zero_extend:DI (match_dup 2))))]
+   "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT"
+   "@
+    slgfr\\t%0,%2
+    slgf\\t%0,%2"
+   [(set_attr "op_type"  "RRE,RXE")
+    (set_attr "atype"    "reg,mem")])
+
+ (define_insn "*subdi3_zero_cconly"
+   [(set (reg 33)
+         (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
+                            (zero_extend:DI (match_operand:SI 2
"general_operand" "d,m")))
+                  (const_int 0)))
+    (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,RXE")
+    (set_attr "atype"    "reg,mem")])
+
+ (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"))))
+    (clobber (reg:CC 33))]
+   "TARGET_64BIT"
+   "@
+    slgfr\\t%0,%2
+    slgf\\t%0,%2"
+   [(set_attr "op_type"  "RRE,RXE")
+    (set_attr "atype"    "reg,mem")])
+
+ (define_insn "*subdi3_cc"
+   [(set (reg 33)
+         (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
+                            (match_operand:DI 2 "general_operand" "d,m"))
+                  (const_int 0)))
+    (set (match_operand:DI 0 "register_operand" "=d,d")
+         (minus:DI (match_dup 1) (match_dup 2)))]
+   "s390_match_ccmode (insn, CCLmode)"
+   "@
+    slgr\\t%0,%2
+    slg\\t%0,%2"
+   [(set_attr "op_type"  "RRE,RXE")
+    (set_attr "atype"    "reg,mem")])
+
+ (define_insn "*subdi3_cconly"
+   [(set (reg 33)
+         (compare (minus:DI (match_operand:DI 1 "register_operand" "0,0")
+                            (match_operand:DI 2 "general_operand" "d,m"))
+                  (const_int 0)))
+    (clobber (match_scratch:DI 0 "=d,d"))]
+   "s390_match_ccmode (insn, CCLmode)"
+   "@
+    slgr\\t%0,%2
+    slg\\t%0,%2"
+   [(set_attr "op_type"  "RRE,RXE")
+    (set_attr "atype"    "reg,mem")])
+
  (define_insn "*subdi3_64"
    [(set (match_operand:DI 0 "register_operand" "=d,d")
          (minus:DI (match_operand:DI 1 "register_operand" "0,0")
***************
*** 3381,3421 ****
    [(set_attr "op_type"  "RRE,RRE")
     (set_attr "atype"    "reg,mem")])

! (define_insn "subdi3"
!   [(set (match_operand:DI 0 "register_operand" "=d,d")
!         (minus:DI (match_operand:DI 1 "register_operand" "0,0")
!                   (match_operand:DI 2 "general_operand" "d,m")))
     (clobber (reg:CC 33))]
!   ""
!   "*
! {
!    switch (which_alternative)
!      {
!      case 0: /* d <- d */
!        output_asm_insn (\"sr\\t%0,%2\", operands);
!        output_asm_insn (\"slr\\t%N0,%N2\", operands);
!        break;
!      case 1: /* d <- m */
!        output_asm_insn (\"s\\t%0,%2\", operands);
!        output_asm_insn (\"sl\\t%N0,%N2\", operands);
!        break;
!
!      default:
!        abort ();
!      }

!    output_asm_insn (\"brc\\t11,.+8\", operands);
!    return \"ahi\\t%0,-1\";
! }"
!   [(set_attr "op_type"  "NN,NN")
!    (set_attr "atype"    "reg,mem")
!    (set_attr "type"     "other,other")
!    (set_attr "length"   "12,16")])

  ;
  ; subsi3 instruction pattern(s).
  ;

  (define_insn "*subsi3_cc"
    [(set (reg 33)
          (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0")
--- 3560,3639 ----
    [(set_attr "op_type"  "RRE,RRE")
     (set_attr "atype"    "reg,mem")])

! (define_insn_and_split "*subdi3_31"
!   [(set (match_operand:DI 0 "register_operand" "=&d")
!         (minus:DI (match_operand:DI 1 "register_operand" "0")
!                   (match_operand:DI 2 "general_operand" "dm") ) )
     (clobber (reg:CC 33))]
!   "!TARGET_64BIT"
!   "#"
!   "&& reload_completed"
!   [(parallel
!     [(set (match_dup 3) (minus:SI (match_dup 4) (match_dup 5)))
!      (clobber (reg:CC 33))])
!    (parallel
!     [(set (reg:CCL2 33)
!           (compare:CCL2 (minus:SI (match_dup 7) (match_dup 8))
!                         (match_dup 7)))
!      (set (match_dup 6) (minus:SI (match_dup 7) (match_dup 8)))])
!    (set (pc)
!         (if_then_else (gtu (reg:CCL2 33) (const_int 0))
!                       (pc)
!                       (label_ref (match_dup 9))))
!    (parallel
!     [(set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))
!      (clobber (reg:CC 33))])
!    (match_dup 9)]
!   "operands[3] = operand_subword (operands[0], 0, 1, DImode);
!    operands[4] = operand_subword (operands[1], 0, 1, DImode);
!    operands[5] = operand_subword (operands[2], 0, 1, DImode);
!    operands[6] = operand_subword (operands[0], 1, 1, DImode);
!    operands[7] = operand_subword (operands[1], 1, 1, DImode);
!    operands[8] = operand_subword (operands[2], 1, 1, DImode);
!    operands[9] = gen_label_rtx ();"
!   [(set_attr "op_type"  "NN")
!    (set_attr "type"     "o3")])

! (define_expand "subdi3"
!   [(parallel
!     [(set (match_operand:DI 0 "register_operand" "")
!           (minus:DI (match_operand:DI 1 "register_operand" "")
!                     (match_operand:DI 2 "general_operand" "")))
!      (clobber (reg:CC 33))])]
!   ""
!   "")

  ;
  ; subsi3 instruction pattern(s).
  ;

+ (define_insn "*subsi3_borrow_cc"
+   [(set (reg 33)
+         (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0")
+                            (match_operand:SI 2 "general_operand" "d,m"))
+                  (match_dup 1)))
+    (set (match_operand:SI 0 "register_operand" "=d,d")
+         (minus:SI (match_dup 1) (match_dup 2)))]
+   "s390_match_ccmode(insn, CCL2mode)"
+   "@
+    slr\\t%0,%2
+    sl\\t%0,%2"
+   [(set_attr "op_type"  "RR,RX")
+    (set_attr "atype"    "reg,mem")])
+
+ (define_insn "*subsi3_borrow_cconly"
+   [(set (reg 33)
+         (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0")
+                            (match_operand:SI 2 "general_operand" "d,m"))
+                  (match_dup 1)))
+    (clobber (match_scratch:SI 0 "=d,d"))]
+   "s390_match_ccmode(insn, CCL2mode)"
+   "@
+    slr\\t%0,%2
+    sl\\t%0,%2"
+   [(set_attr "op_type"  "RR,RX")
+    (set_attr "atype"    "reg,mem")])
+
  (define_insn "*subsi3_cc"
    [(set (reg 33)
          (compare (minus:SI (match_operand:SI 1 "register_operand" "0,0")
***************
*** 3443,3448 ****
--- 3661,3686 ----
    [(set_attr "op_type"  "RR,RX")
     (set_attr "atype"    "reg,mem")])

+ (define_insn "*subsi3_sign"
+   [(set (match_operand:SI 0 "register_operand" "=d")
+         (minus:SI (match_operand:SI 1 "register_operand" "0")
+                   (sign_extend:SI (match_operand:HI 2 "memory_operand"
"m"))))
+    (clobber (reg:CC 33))]
+   ""
+   "sh\\t%0,%2"
+   [(set_attr "op_type"  "RX")
+    (set_attr "atype"    "mem")])
+
+ (define_insn "*subsi3_sub"
+   [(set (match_operand:SI 0 "register_operand" "=d")
+         (minus:SI (match_operand:SI 1 "register_operand" "0")
+                   (subreg:SI (match_operand:HI 2 "memory_operand" "m")
0)))
+    (clobber (reg:CC 33))]
+   ""
+   "sh\\t%0,%2"
+   [(set_attr "op_type"  "RX")
+    (set_attr "atype"    "mem")])
+
  (define_insn "subsi3"
    [(set (match_operand:SI 0 "register_operand" "=d,d")
          (minus:SI (match_operand:SI 1 "register_operand" "0,0")
***************
*** 3455,3488 ****
    [(set_attr "op_type"  "RR,RX")
     (set_attr "atype"    "reg,mem")])

- ;
- ; subhi3 instruction pattern(s).
- ;
-
- (define_insn "subhi3"
-   [(set (match_operand:HI 0 "register_operand" "=d,d")
-         (minus:HI (match_operand:HI 1 "register_operand" "0,0")
-                   (match_operand:HI 2 "general_operand" "d,m")))
-    (clobber (reg:CC 33))]
-   ""
-   "@
-    sr\\t%0,%2
-    sh\\t%0,%2"
-   [(set_attr "op_type"  "RR,RX")
-    (set_attr "atype"    "reg,mem")])
-
- ;
- ; subqi3 instruction pattern(s).
- ;
-
- (define_insn "subqi3"
-   [(set (match_operand:QI 0 "register_operand" "=d")
-         (minus:QI (match_operand:QI 1 "register_operand" "0")
-                   (match_operand:QI 2 "register_operand" "d")))
-    (clobber (reg:CC 33))]
-   ""
-   "sr\\t%0,%2"
-    [(set_attr "op_type"  "RR")])

  ;
  ; subdf3 instruction pattern(s).
--- 3693,3698 ----
***************
*** 3567,3583 ****
  ; muldi3 instruction pattern(s).
  ;

  (define_insn "muldi3"
    [(set (match_operand:DI 0 "register_operand" "=d,d,d")
          (mult:DI (match_operand:DI 1 "register_operand" "%0,0,0")
!                  (match_operand:DI 2 "general_operand" "d,K,m")))
!    (clobber (reg:CC 33))]
    "TARGET_64BIT"
    "@
     msgr\\t%0,%2
     mghi\\t%0,%h2
     msg\\t%0,%2"
!   [(set_attr "op_type"  "RRE,RI,RX")
     (set_attr "atype"    "reg,reg,mem")
     (set_attr "type"     "imul")])

--- 3777,3805 ----
  ; muldi3 instruction pattern(s).
  ;

+ (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"))
+                  (match_operand:DI 1 "register_operand" "0,0")))]
+   "TARGET_64BIT"
+   "@
+    msgfr\\t%0,%2
+    msgf\\t%0,%2"
+   [(set_attr "op_type"  "RRE,RXE")
+    (set_attr "atype"    "reg,mem")
+    (set_attr "type"     "imul")])
+
+
  (define_insn "muldi3"
    [(set (match_operand:DI 0 "register_operand" "=d,d,d")
          (mult:DI (match_operand:DI 1 "register_operand" "%0,0,0")
!                  (match_operand:DI 2 "general_operand" "d,K,m")))]
    "TARGET_64BIT"
    "@
     msgr\\t%0,%2
     mghi\\t%0,%h2
     msg\\t%0,%2"
!   [(set_attr "op_type"  "RRE,RI,RXE")
     (set_attr "atype"    "reg,reg,mem")
     (set_attr "type"     "imul")])

***************
*** 3588,3595 ****
  (define_insn "mulsi3"
    [(set (match_operand:SI 0 "register_operand" "=d,d,d")
          (mult:SI  (match_operand:SI 1 "register_operand" "%0,0,0")
!                   (match_operand:SI 2 "general_operand" "d,K,m")))
!    (clobber (reg:CC 33))]
    ""
    "@
     msr\\t%0,%2
--- 3810,3816 ----
  (define_insn "mulsi3"
    [(set (match_operand:SI 0 "register_operand" "=d,d,d")
          (mult:SI  (match_operand:SI 1 "register_operand" "%0,0,0")
!                   (match_operand:SI 2 "general_operand" "d,K,m")))]
    ""
    "@
     msr\\t%0,%2
***************
*** 3629,3636 ****
           (mult:DI (sign_extend:DI
                  (truncate:SI (match_operand:DI 1 "register_operand"
"0,0")))
                    (sign_extend:DI
!                 (match_operand:SI 2 "nonimmediate_operand" "d,m"))))
!     (clobber (reg:CC 33))]
     "!TARGET_64BIT"
     "@
      mr\\t%0,%2
--- 3850,3856 ----
           (mult:DI (sign_extend:DI
                  (truncate:SI (match_operand:DI 1 "register_operand"
"0,0")))
                    (sign_extend:DI
!                 (match_operand:SI 2 "nonimmediate_operand" "d,m"))))]
     "!TARGET_64BIT"
     "@
      mr\\t%0,%2


Mit freundlichen Gruessen / Best Regards

Ulrich Weigand

--
  Dr. Ulrich Weigand
  Linux for S/390 Design & Development
  IBM Deutschland Entwicklung GmbH, Schoenaicher Str. 220, 71032 Boeblingen
  Phone: +49-7031/16-3727   ---   Email: Ulrich.Weigand@de.ibm.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]