OSDN Git Service

* config/s390/s390.c (s390_canonicalize_comparison): Reverse condition
authoruweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 9 Nov 2004 15:47:48 +0000 (15:47 +0000)
committeruweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 9 Nov 2004 15:47:48 +0000 (15:47 +0000)
when eliminating an UNSPEC_CMPINT.
(s390_secondary_input_reload_class): Fix test for CC register reload.
(s390_secondary_output_reload_class): Likewise.
(s390_expand_cmpmem): Swap operands.  Use gen_cmpint.
* config/s390/s390.md ("*cmpint_si", "*cmpint_di"): Remove.
("cmpint", "*cmpint_cc", "*cmpint_sign", "*cmpint_sign_cc"): New
insn patterns with splitters.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@90346 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/s390/s390.c
gcc/config/s390/s390.md

index baaecc2..c5737d5 100644 (file)
@@ -1,3 +1,14 @@
+2004-11-09  Ulrich Weigand  <uweigand@de.ibm.com>
+
+       * config/s390/s390.c (s390_canonicalize_comparison): Reverse condition
+       when eliminating an UNSPEC_CMPINT.
+       (s390_secondary_input_reload_class): Fix test for CC register reload.
+       (s390_secondary_output_reload_class): Likewise.
+       (s390_expand_cmpmem): Swap operands.  Use gen_cmpint. 
+       * config/s390/s390.md ("*cmpint_si", "*cmpint_di"): Remove.
+       ("cmpint", "*cmpint_cc", "*cmpint_sign", "*cmpint_sign_cc"): New
+       insn patterns with splitters.
+
 2004-11-09  David Edelsohn  <edelsohn@gnu.org>
 
        * config/rs6000/rs6000.c (rs6000_rtx_costs): Add EQ, GTU, and LTU.
index b4b4c45..16018c6 100644 (file)
@@ -624,10 +624,10 @@ s390_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1)
        {
          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;
+         case LT: new_code = GTU; break;
+         case GT: new_code = LTU; break;
+         case LE: new_code = GEU; break;
+         case GE: new_code = LEU; break;
          default: break;
        }
 
@@ -2291,13 +2291,13 @@ s390_preferred_reload_class (rtx op, enum reg_class class)
    is not a legitimate operand of the LOAD ADDRESS instruction.  */
 
 enum reg_class
-s390_secondary_input_reload_class (enum reg_class class ATTRIBUTE_UNUSED,
+s390_secondary_input_reload_class (enum reg_class class,
                                   enum machine_mode mode, rtx in)
 {
   if (s390_plus_operand (in, mode))
     return ADDR_REGS;
 
-  if (GET_MODE_CLASS (mode) == MODE_CC)
+  if (reg_classes_intersect_p (CC_REGS, class))
     return GENERAL_REGS;
 
   return NO_REGS;
@@ -2321,7 +2321,7 @@ s390_secondary_output_reload_class (enum reg_class class,
       && !s_operand (out, VOIDmode))
     return ADDR_REGS;
 
-  if (GET_MODE_CLASS (mode) == MODE_CC)
+  if (reg_classes_intersect_p (CC_REGS, class))
     return GENERAL_REGS;
 
   return NO_REGS;
@@ -3593,14 +3593,18 @@ void
 s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len)
 {
   rtx ccreg = gen_rtx_REG (CCUmode, CC_REGNUM);
-  rtx result = gen_rtx_UNSPEC (SImode, gen_rtvec (1, ccreg), UNSPEC_CMPINT);
+  rtx tmp;
+
+  /* As the result of CMPINT is inverted compared to what we need,
+     we have to swap the operands.  */
+  tmp = op0; op0 = op1; op1 = tmp;
 
   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_move_insn (target, result);
+          emit_insn (gen_cmpint (target, ccreg));
         }
       else
         emit_move_insn (target, const0_rtx);
@@ -3608,7 +3612,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_move_insn (target, result);
+      emit_insn (gen_cmpint (target, ccreg));
     }
   else
     {
@@ -3675,7 +3679,7 @@ s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len)
                                   convert_to_mode (Pmode, count, 1)));
       emit_label (end_label);
 
-      emit_move_insn (target, result);
+      emit_insn (gen_cmpint (target, ccreg));
     }
 }
 
index 7444859..3f3f28a 100644 (file)
   [(set_attr "length" "8")
    (set_attr "type" "vs")])
 
-; Convert condition code to integer in range (-1, 0, 1)
+; Convert CCUmode condition code to integer.
+; Result is zero if EQ, positive if LTU, negative if GTU.
 
-(define_insn "*cmpint_si"
+(define_insn_and_split "cmpint"
   [(set (match_operand:SI 0 "register_operand" "=d")
-        (unspec:SI [(reg:CCU 33)] UNSPEC_CMPINT))]
+        (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
+                   UNSPEC_CMPINT))
+   (clobber (reg:CC 33))]
   ""
+  "#"
+  "reload_completed"
+  [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
+   (parallel
+    [(set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))
+     (clobber (reg:CC 33))])])
+
+(define_insn_and_split "*cmpint_cc"
+  [(set (reg 33)
+        (compare (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
+                            UNSPEC_CMPINT)
+                 (const_int 0)))
+   (set (match_operand:SI 0 "register_operand" "=d")
+        (unspec:SI [(match_dup 1)] UNSPEC_CMPINT))]
+  "s390_match_ccmode (insn, CCSmode)"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 0) (ashift:SI (match_dup 0) (const_int 2)))
+   (parallel
+    [(set (match_dup 2) (match_dup 3))
+     (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 30)))])]
 {
-   output_asm_insn ("lhi\t%0,1", operands);
-   output_asm_insn ("jh\t.+12", operands);
-   output_asm_insn ("jl\t.+6", operands);
-   output_asm_insn ("sr\t%0,%0", operands);
-   return "lcr\t%0,%0";
-}
-  [(set_attr "length" "16")])
+  rtx result = gen_rtx_ASHIFTRT (SImode, operands[0], GEN_INT (30));
+  operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
+  operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
+})
 
-(define_insn "*cmpint_di"
+(define_insn_and_split "*cmpint_sign"
   [(set (match_operand:DI 0 "register_operand" "=d")
-        (sign_extend:DI (unspec:SI [(reg:CCU 33)] UNSPEC_CMPINT)))]
+        (sign_extend:DI (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
+                                   UNSPEC_CMPINT)))
+   (clobber (reg:CC 33))]
   "TARGET_64BIT"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
+   (parallel
+    [(set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))
+     (clobber (reg:CC 33))])])
+
+(define_insn_and_split "*cmpint_sign_cc"
+  [(set (reg 33)
+        (compare (ashiftrt:DI (ashift:DI (subreg:DI 
+                   (unspec:SI [(match_operand:CCU 1 "register_operand" "0")]
+                              UNSPEC_CMPINT) 0)
+                   (const_int 32)) (const_int 32))
+                 (const_int 0)))
+   (set (match_operand:DI 0 "register_operand" "=d")
+        (sign_extend:DI (unspec:SI [(match_dup 1)] UNSPEC_CMPINT)))]
+  "s390_match_ccmode (insn, CCSmode) && TARGET_64BIT"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 0) (ashift:DI (match_dup 0) (const_int 34)))
+   (parallel
+    [(set (match_dup 2) (match_dup 3))
+     (set (match_dup 0) (ashiftrt:DI (match_dup 0) (const_int 62)))])]
 {
-   output_asm_insn ("lghi\t%0,1", operands);
-   output_asm_insn ("jh\t.+16", operands);
-   output_asm_insn ("jl\t.+8", operands);
-   output_asm_insn ("sgr\t%0,%0", operands);
-   return "lcgr\t%0,%0";
-}
-  [(set_attr "length" "20")])
+  rtx result = gen_rtx_ASHIFTRT (DImode, operands[0], GEN_INT (62));
+  operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
+  operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
+})
 
 
 ;;