diff options
author | Ulrich Weigand <uweigand@de.ibm.com> | 2004-11-09 15:47:48 +0000 |
---|---|---|
committer | Ulrich Weigand <uweigand@gcc.gnu.org> | 2004-11-09 15:47:48 +0000 |
commit | 0288742581805950c85deeaa71a8915d8617e894 (patch) | |
tree | 3462315bc1cb2785c1537fafcdb1081f6a6be655 | |
parent | c0600ecd541e2e57c72bb7e478b0eb72fe5a1a27 (diff) | |
download | gcc-0288742581805950c85deeaa71a8915d8617e894.zip gcc-0288742581805950c85deeaa71a8915d8617e894.tar.gz gcc-0288742581805950c85deeaa71a8915d8617e894.tar.bz2 |
s390.c (s390_canonicalize_comparison): Reverse condition when eliminating an UNSPEC_CMPINT.
* 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.
From-SVN: r90346
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/config/s390/s390.c | 26 | ||||
-rw-r--r-- | gcc/config/s390/s390.md | 81 |
3 files changed, 88 insertions, 30 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index baaecc2..c5737d5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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. diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index b4b4c45..16018c6 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -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)); } } diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 7444859..3f3f28a 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -2276,33 +2276,76 @@ [(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); +}) ;; |