s390-protos.h (s390_comparison): Add prototype.
authorUlrich Weigand <uweigand@de.ibm.com>
Fri, 1 Oct 2004 21:48:13 +0000 (21:48 +0000)
committerUlrich Weigand <uweigand@gcc.gnu.org>
Fri, 1 Oct 2004 21:48:13 +0000 (21:48 +0000)
* config/s390/s390-protos.h (s390_comparison): Add prototype.
* config/s390/s390.c (s390_comparison): New function.
(s390_branch_condition_mask): Return -1 for invalid comparisons.
(s390_branch_condition_mnemonic): Assert valid comparison.
* config/s390/s390.h (PREDICATE_CODES): Add s390_comparison.
* config/s390/s390.md ("*cjump_64", "*cjump_31", "*cjump_long",
"*icjump_64", "*icjump_31", "*icjump_long", "*trap"): Use
s390_comparison instead of comparison_operator.

* config/s390/s390.md (UNSPEC_CMPINT): New constant.
("cmpmemdi"): Remove.
("cmpmem_short", "*cmpmem_short"): Use CCUmode instead of CCSmode.
("cmpmem_long", "*cmpmem_long_64", "*cmpmem_long_31"): Likewise.
("cmpint_si"): Rename to ...
("*cmpint_si"): ... this.  Use UNSPEC_CMPINT.
("cmpint_di", "*cmpint_di"): Likewise.
* config/s390/s390.c (s390_canonicalize_comparison): Remove
redundant UNSPEC_CMPINT conversions.
(s390_expand_cmpmem): Adapt to cmpint pattern changes.

From-SVN: r88410

gcc/ChangeLog
gcc/config/s390/s390-protos.h
gcc/config/s390/s390.c
gcc/config/s390/s390.h
gcc/config/s390/s390.md

index 4abd51e7bd765d313155f3ffbc63d0c06d38049f..9e3acb9c7c6d334796baa114aab72de98df26ead 100644 (file)
@@ -1,3 +1,25 @@
+2004-10-01  Ulrich Weigand  <uweigand@de.ibm.com>
+
+       * config/s390/s390-protos.h (s390_comparison): Add prototype.
+       * config/s390/s390.c (s390_comparison): New function.
+       (s390_branch_condition_mask): Return -1 for invalid comparisons.
+       (s390_branch_condition_mnemonic): Assert valid comparison.
+       * config/s390/s390.h (PREDICATE_CODES): Add s390_comparison.
+       * config/s390/s390.md ("*cjump_64", "*cjump_31", "*cjump_long",
+       "*icjump_64", "*icjump_31", "*icjump_long", "*trap"): Use
+       s390_comparison instead of comparison_operator.
+
+       * config/s390/s390.md (UNSPEC_CMPINT): New constant.
+       ("cmpmemdi"): Remove.
+       ("cmpmem_short", "*cmpmem_short"): Use CCUmode instead of CCSmode.
+       ("cmpmem_long", "*cmpmem_long_64", "*cmpmem_long_31"): Likewise.
+       ("cmpint_si"): Rename to ...
+       ("*cmpint_si"): ... this.  Use UNSPEC_CMPINT.
+       ("cmpint_di", "*cmpint_di"): Likewise.
+       * config/s390/s390.c (s390_canonicalize_comparison): Remove
+       redundant UNSPEC_CMPINT conversions.
+       (s390_expand_cmpmem): Adapt to cmpint pattern changes.
+
 2004-10-01  Kazu Hirata  <kazu@cs.umass.edu>
 
        * collect2.c (COLLECT_PARSE_FLAG): Remove.
index 8846f25c31039943b66fb5ceffe7d5424cbae13a..78b90a8b32c2fdebed7e536c84ceaf0934b3e3eb 100644 (file)
@@ -51,6 +51,7 @@ extern int s390_match_ccmode (rtx, enum machine_mode);
 extern enum machine_mode s390_tm_ccmode (rtx, rtx, int);
 extern enum machine_mode s390_select_ccmode (enum rtx_code, rtx, rtx);
 extern void s390_canonicalize_comparison (enum rtx_code *, rtx *, rtx *);
+extern int s390_comparison (rtx op, enum machine_mode mode);
 extern int s390_alc_comparison (rtx op, enum machine_mode mode);
 extern int s390_slb_comparison (rtx op, enum machine_mode mode);
 extern rtx s390_emit_compare (enum rtx_code, rtx, rtx);
index 411b06f7f32d4be2438d561edb974f03922a19dc..21679c3ea81c52a8b1dc03d7e02c4dbf2a18c502 100644 (file)
@@ -592,7 +592,6 @@ s390_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1)
     }
 
   /* Narrow comparisons against 0xffff to HImode if possible.  */
-
   if ((*code == EQ || *code == NE)
       && GET_CODE (*op1) == CONST_INT
       && INTVAL (*op1) == 0xffff
@@ -603,6 +602,35 @@ s390_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1)
       *op0 = gen_lowpart (HImode, *op0);
       *op1 = constm1_rtx;
     }
+
+
+  /* Remove redundant UNSPEC_CMPINT conversions if possible.  */
+  if (GET_CODE (*op0) == UNSPEC
+      && XINT (*op0, 1) == UNSPEC_CMPINT
+      && XVECLEN (*op0, 0) == 1
+      && GET_MODE (XVECEXP (*op0, 0, 0)) == CCUmode
+      && GET_CODE (XVECEXP (*op0, 0, 0)) == REG
+      && REGNO (XVECEXP (*op0, 0, 0)) == CC_REGNUM
+      && *op1 == const0_rtx)
+    {
+      enum rtx_code new_code = UNKNOWN;
+      switch (*code)
+       {
+         case EQ: new_code = EQ;  break;
+         case NE: new_code = NE;  break;
+         case LT: new_code = LTU; break;
+         case GT: new_code = GTU; break;
+         case LE: new_code = LEU; break;
+         case GE: new_code = GEU; break;
+         default: break;
+       }
+
+      if (new_code != UNKNOWN)
+       {
+         *op0 = XVECEXP (*op0, 0, 0);
+         *code = new_code;
+       }
+    }
 }
 
 /* Emit a compare instruction suitable to implement the comparison
@@ -635,6 +663,26 @@ s390_emit_jump (rtx target, rtx cond)
   emit_jump_insn (insn);
 }
 
+/* Return nonzero if OP is a valid comparison operator
+   for a branch condition in mode MODE.  */
+
+int
+s390_comparison (rtx op, enum machine_mode mode)
+{
+  if (mode != VOIDmode && mode != GET_MODE (op))
+    return 0;
+
+  if (!COMPARISON_P (op))
+    return 0;
+
+  if (GET_CODE (XEXP (op, 0)) != REG
+      || REGNO (XEXP (op, 0)) != CC_REGNUM
+      || XEXP (op, 1) != const0_rtx)
+    return 0;
+
+  return s390_branch_condition_mask (op) >= 0;
+}
+
 /* Return nonzero if OP is a valid comparison operator
    for an ALC condition in mode MODE.  */
 
@@ -732,7 +780,7 @@ s390_slb_comparison (rtx op, enum machine_mode mode)
 }
 
 /* Return branch condition mask to implement a branch
-   specified by CODE.  */
+   specified by CODE.  Return -1 for invalid comparisons.  */
 
 static int
 s390_branch_condition_mask (rtx code)
@@ -754,8 +802,7 @@ s390_branch_condition_mask (rtx code)
         {
         case EQ:       return CC0;
        case NE:        return CC1 | CC2 | CC3;
-       default:
-         abort ();
+       default:        return -1;
         }
       break;
 
@@ -764,8 +811,7 @@ s390_branch_condition_mask (rtx code)
         {
         case EQ:       return CC1;
        case NE:        return CC0 | CC2 | CC3;
-       default:
-         abort ();
+       default:        return -1;
         }
       break;
 
@@ -774,8 +820,7 @@ s390_branch_condition_mask (rtx code)
         {
         case EQ:       return CC2;
        case NE:        return CC0 | CC1 | CC3;
-       default:
-         abort ();
+       default:        return -1;
         }
       break;
 
@@ -784,8 +829,7 @@ s390_branch_condition_mask (rtx code)
         {
         case EQ:       return CC3;
        case NE:        return CC0 | CC1 | CC2;
-       default:
-         abort ();
+       default:        return -1;
         }
       break;
 
@@ -794,8 +838,7 @@ s390_branch_condition_mask (rtx code)
         {
         case EQ:       return CC0 | CC2;
        case NE:        return CC1 | CC3;
-       default:
-         abort ();
+       default:        return -1;
         }
       break;
 
@@ -804,8 +847,7 @@ s390_branch_condition_mask (rtx code)
         {
        case LTU:       return CC2 | CC3;  /* carry */
        case GEU:       return CC0 | CC1;  /* no carry */
-       default:
-         abort ();
+       default:        return -1;
         }
       break;
 
@@ -814,8 +856,7 @@ s390_branch_condition_mask (rtx code)
         {
        case GTU:       return CC0 | CC1;  /* borrow */
        case LEU:       return CC2 | CC3;  /* no borrow */
-       default:
-         abort ();
+       default:        return -1;
         }
       break;
 
@@ -828,8 +869,7 @@ s390_branch_condition_mask (rtx code)
        case GTU:       return CC3;
        case LEU:       return CC1 | CC2;
        case GEU:       return CC2 | CC3;
-       default:
-         abort ();
+       default:        return -1;
        }
 
     case CCUmode:
@@ -841,8 +881,7 @@ s390_branch_condition_mask (rtx code)
         case GTU:      return CC2;
         case LEU:      return CC0 | CC1;
         case GEU:      return CC0 | CC2;
-       default:
-         abort ();
+       default:        return -1;
         }
       break;
 
@@ -855,8 +894,7 @@ s390_branch_condition_mask (rtx code)
         case GTU:      return CC1;
         case LEU:      return CC0 | CC2;
         case GEU:      return CC0 | CC1;
-       default:
-         abort ();
+       default:        return -1;
         }
       break;
 
@@ -869,8 +907,7 @@ s390_branch_condition_mask (rtx code)
         case GT:       return CC2;
         case LE:       return CC0 | CC1 | CC3;
         case GE:       return CC0 | CC2;
-       default:
-         abort ();
+       default:        return -1;
         }
       break;
 
@@ -883,8 +920,7 @@ s390_branch_condition_mask (rtx code)
         case GT:       return CC2 | CC3;
         case LE:       return CC0 | CC1;
         case GE:       return CC0 | CC2 | CC3;
-       default:
-         abort ();
+       default:        return -1;
         }
       break;
 
@@ -905,8 +941,7 @@ s390_branch_condition_mask (rtx code)
         case UNLE:     return CC0 | CC1 | CC3;
         case UNGE:     return CC0 | CC2 | CC3;
        case LTGT:      return CC1 | CC2;
-       default:
-         abort ();
+       default:        return -1;
         }
       break;
 
@@ -927,13 +962,12 @@ s390_branch_condition_mask (rtx code)
         case UNLE:     return CC0 | CC2 | CC3;
         case UNGE:     return CC0 | CC1 | CC3;
        case LTGT:      return CC2 | CC1;
-       default:
-         abort ();
+       default:        return -1;
         }
       break;
 
     default:
-      abort ();
+      return -1;
     }
 }
 
@@ -953,6 +987,7 @@ s390_branch_condition_mnemonic (rtx code, int inv)
     };
 
   int mask = s390_branch_condition_mask (code);
+  gcc_assert (mask >= 0);
 
   if (inv)
     mask ^= 15;
@@ -3486,15 +3521,15 @@ s390_expand_clrmem (rtx dst, rtx len)
 void
 s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len)
 {
-  rtx (*gen_result) (rtx) =
-    GET_MODE (target) == DImode ? gen_cmpint_di : gen_cmpint_si;
+  rtx ccreg = gen_rtx_REG (CCUmode, CC_REGNUM);
+  rtx result = gen_rtx_UNSPEC (SImode, gen_rtvec (1, ccreg), UNSPEC_CMPINT);
 
   if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
     {
       if (INTVAL (len) > 0)
         {
           emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (INTVAL (len) - 1)));
-          emit_insn (gen_result (target));
+          emit_move_insn (target, result);
         }
       else
         emit_move_insn (target, const0_rtx);
@@ -3503,7 +3538,7 @@ s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len)
   else /* if (TARGET_MVCLE) */
     {
       emit_insn (gen_cmpmem_long (op0, op1, convert_to_mode (Pmode, len, 1)));
-      emit_insn (gen_result (target));
+      emit_move_insn (target, result);
     }
 
 #if 0
@@ -3549,7 +3584,7 @@ s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len)
       emit_label (loop_start_label);
 
       emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (255)));
-      temp = gen_rtx_NE (VOIDmode, gen_rtx_REG (CCSmode, 33), const0_rtx);
+      temp = gen_rtx_NE (VOIDmode, ccreg, const0_rtx);
       temp = gen_rtx_IF_THEN_ELSE (VOIDmode, temp,
                        gen_rtx_LABEL_REF (VOIDmode, end_label), pc_rtx);
       temp = gen_rtx_SET (VOIDmode, pc_rtx, temp);
@@ -3574,7 +3609,7 @@ s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len)
                                   convert_to_mode (Pmode, count, 1)));
       emit_label (end_label);
 
-      emit_insn (gen_result (target));
+      emit_move_insn (target, result);
     }
 #endif
 }
index 9814561e0526b3be1e7d7f14fb71e5ee03bd66b3..4d50395b67c450c180bf1799ec38383e93317ba0 100644 (file)
@@ -1025,6 +1025,9 @@ do {                                                                      \
   {"consttable_operand", { SYMBOL_REF, LABEL_REF, CONST,               \
                           CONST_INT, CONST_DOUBLE }},                  \
   {"s390_plus_operand", { PLUS }},                                     \
+  {"s390_comparison",     { EQ, NE, LT, GT, LE, GE, LTU, GTU, LEU, GEU,        \
+                           UNEQ, UNLT, UNGT, UNLE, UNGE, LTGT,         \
+                           UNORDERED, ORDERED }},                      \
   {"s390_alc_comparison", { ZERO_EXTEND, SIGN_EXTEND,                  \
                            LTU, GTU, LEU, GEU }},                      \
   {"s390_slb_comparison", { ZERO_EXTEND, SIGN_EXTEND,                  \
index 86d13b8a871889970f696632304ee691ec737984..a2408d751964d45d5ceda7bf89dec16c0995d37d 100644 (file)
@@ -78,6 +78,7 @@
 (define_constants
   [; Miscellaneous
    (UNSPEC_ROUND               1)
+   (UNSPEC_CMPINT              2)
    (UNSPEC_SETHIGH             10)
 
    ; GOT/PLT and lt-relative accesses
 ; cmpmemM instruction pattern(s).
 ;
 
-(define_expand "cmpmemdi"
-  [(set (match_operand:DI 0 "register_operand" "")
-        (compare:DI (match_operand:BLK 1 "memory_operand" "")
-                    (match_operand:BLK 2 "memory_operand" "") ) )
-   (use (match_operand:DI 3 "general_operand" ""))
-   (use (match_operand:DI 4 "" ""))]
-  "TARGET_64BIT"
-  "s390_expand_cmpmem (operands[0], operands[1],
-                       operands[2], operands[3]); DONE;")
-
 (define_expand "cmpmemsi"
   [(set (match_operand:SI 0 "register_operand" "")
         (compare:SI (match_operand:BLK 1 "memory_operand" "")
 
 (define_expand "cmpmem_short"
   [(parallel
-    [(set (reg:CCS 33)
-          (compare:CCS (match_operand:BLK 0 "memory_operand" "")
+    [(set (reg:CCU 33)
+          (compare:CCU (match_operand:BLK 0 "memory_operand" "")
                        (match_operand:BLK 1 "memory_operand" "")))
      (use (match_operand 2 "nonmemory_operand" ""))
      (clobber (match_dup 3))])]
   "operands[3] = gen_rtx_SCRATCH (Pmode);")
 
 (define_insn "*cmpmem_short"
-  [(set (reg:CCS 33)
-        (compare:CCS (match_operand:BLK 0 "memory_operand" "=Q,Q")
+  [(set (reg:CCU 33)
+        (compare:CCU (match_operand:BLK 0 "memory_operand" "=Q,Q")
                      (match_operand:BLK 1 "memory_operand" "Q,Q")))
    (use (match_operand 2 "nonmemory_operand" "n,a"))
    (clobber (match_scratch 3 "=X,&a"))]
   [(parallel
     [(clobber (match_dup 2))
      (clobber (match_dup 3))
-     (set (reg:CCS 33)
-          (compare:CCS (match_operand:BLK 0 "memory_operand" "")
+     (set (reg:CCU 33)
+          (compare:CCU (match_operand:BLK 0 "memory_operand" "")
                        (match_operand:BLK 1 "memory_operand" "")))
      (use (match_operand 2 "general_operand" ""))
      (use (match_dup 3))])]
 (define_insn "*cmpmem_long_64"
   [(clobber (match_operand:TI 0 "register_operand" "=d"))
    (clobber (match_operand:TI 1 "register_operand" "=d"))
-   (set (reg:CCS 33)
-        (compare:CCS (mem:BLK (subreg:DI (match_operand:TI 2 "register_operand" "0") 0))
+   (set (reg:CCU 33)
+        (compare:CCU (mem:BLK (subreg:DI (match_operand:TI 2 "register_operand" "0") 0))
                      (mem:BLK (subreg:DI (match_operand:TI 3 "register_operand" "1") 0))))
    (use (match_dup 2))
    (use (match_dup 3))]
 (define_insn "*cmpmem_long_31"
   [(clobber (match_operand:DI 0 "register_operand" "=d"))
    (clobber (match_operand:DI 1 "register_operand" "=d"))
-   (set (reg:CCS 33)
-        (compare:CCS (mem:BLK (subreg:SI (match_operand:DI 2 "register_operand" "0") 0))
+   (set (reg:CCU 33)
+        (compare:CCU (mem:BLK (subreg:SI (match_operand:DI 2 "register_operand" "0") 0))
                      (mem:BLK (subreg:SI (match_operand:DI 3 "register_operand" "1") 0))))
    (use (match_dup 2))
    (use (match_dup 3))]
 
 ; Convert condition code to integer in range (-1, 0, 1)
 
-(define_insn "cmpint_si"
+(define_insn "*cmpint_si"
   [(set (match_operand:SI 0 "register_operand" "=d")
-        (compare:SI (reg:CCS 33) (const_int 0)))]
+        (unspec:SI [(reg:CCU 33)] UNSPEC_CMPINT))]
   ""
 {
    output_asm_insn ("lhi\t%0,1", operands);
    (set_attr "length"  "16")
    (set_attr "type"    "other")])
 
-(define_insn "cmpint_di"
+(define_insn "*cmpint_di"
   [(set (match_operand:DI 0 "register_operand" "=d")
-        (compare:DI (reg:CCS 33) (const_int 0)))]
+        (sign_extend:DI (unspec:SI [(reg:CCU 33)] UNSPEC_CMPINT)))]
   "TARGET_64BIT"
 {
    output_asm_insn ("lghi\t%0,1", operands);
 (define_insn "*cjump_64"
   [(set (pc)
         (if_then_else
-          (match_operator 1 "comparison_operator" [(reg 33) (const_int 0)])
+          (match_operator 1 "s390_comparison" [(reg 33) (const_int 0)])
           (label_ref (match_operand 0 "" ""))
           (pc)))]
   "TARGET_CPU_ZARCH"
 (define_insn "*cjump_31"
   [(set (pc)
         (if_then_else
-          (match_operator 1 "comparison_operator" [(reg 33) (const_int 0)])
+          (match_operator 1 "s390_comparison" [(reg 33) (const_int 0)])
           (label_ref (match_operand 0 "" ""))
           (pc)))]
   "!TARGET_CPU_ZARCH"
 (define_insn "*cjump_long"
   [(set (pc)
         (if_then_else
-          (match_operator 1 "comparison_operator" [(reg 33) (const_int 0)])
+          (match_operator 1 "s390_comparison" [(reg 33) (const_int 0)])
           (match_operand 0 "address_operand" "U")
           (pc)))]
   ""
 (define_insn "*icjump_64"
   [(set (pc)
         (if_then_else
-          (match_operator 1 "comparison_operator" [(reg 33) (const_int 0)])
+          (match_operator 1 "s390_comparison" [(reg 33) (const_int 0)])
           (pc)
           (label_ref (match_operand 0 "" ""))))]
   "TARGET_CPU_ZARCH"
 (define_insn "*icjump_31"
   [(set (pc)
         (if_then_else
-          (match_operator 1 "comparison_operator" [(reg 33) (const_int 0)])
+          (match_operator 1 "s390_comparison" [(reg 33) (const_int 0)])
           (pc)
           (label_ref (match_operand 0 "" ""))))]
   "!TARGET_CPU_ZARCH"
 (define_insn "*icjump_long"
   [(set (pc)
         (if_then_else
-          (match_operator 1 "comparison_operator" [(reg 33) (const_int 0)])
+          (match_operator 1 "s390_comparison" [(reg 33) (const_int 0)])
           (pc)
           (match_operand 0 "address_operand" "U")))]
   ""
 })
 
 (define_insn "*trap"
-  [(trap_if (match_operator 0 "comparison_operator" [(reg 33) (const_int 0)])
+  [(trap_if (match_operator 0 "s390_comparison" [(reg 33) (const_int 0)])
            (const_int 0))]
   ""
   "j%C0\t.+2";