Commit 02887425 by Ulrich Weigand Committed by Ulrich Weigand

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
parent c0600ecd
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> 2004-11-09 David Edelsohn <edelsohn@gnu.org>
* config/rs6000/rs6000.c (rs6000_rtx_costs): Add EQ, GTU, and LTU. * config/rs6000/rs6000.c (rs6000_rtx_costs): Add EQ, GTU, and LTU.
......
...@@ -624,10 +624,10 @@ s390_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1) ...@@ -624,10 +624,10 @@ s390_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1)
{ {
case EQ: new_code = EQ; break; case EQ: new_code = EQ; break;
case NE: new_code = NE; break; case NE: new_code = NE; break;
case LT: new_code = LTU; break; case LT: new_code = GTU; break;
case GT: new_code = GTU; break; case GT: new_code = LTU; break;
case LE: new_code = LEU; break; case LE: new_code = GEU; break;
case GE: new_code = GEU; break; case GE: new_code = LEU; break;
default: break; default: break;
} }
...@@ -2291,13 +2291,13 @@ s390_preferred_reload_class (rtx op, enum reg_class class) ...@@ -2291,13 +2291,13 @@ s390_preferred_reload_class (rtx op, enum reg_class class)
is not a legitimate operand of the LOAD ADDRESS instruction. */ is not a legitimate operand of the LOAD ADDRESS instruction. */
enum reg_class 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) enum machine_mode mode, rtx in)
{ {
if (s390_plus_operand (in, mode)) if (s390_plus_operand (in, mode))
return ADDR_REGS; return ADDR_REGS;
if (GET_MODE_CLASS (mode) == MODE_CC) if (reg_classes_intersect_p (CC_REGS, class))
return GENERAL_REGS; return GENERAL_REGS;
return NO_REGS; return NO_REGS;
...@@ -2321,7 +2321,7 @@ s390_secondary_output_reload_class (enum reg_class class, ...@@ -2321,7 +2321,7 @@ s390_secondary_output_reload_class (enum reg_class class,
&& !s_operand (out, VOIDmode)) && !s_operand (out, VOIDmode))
return ADDR_REGS; return ADDR_REGS;
if (GET_MODE_CLASS (mode) == MODE_CC) if (reg_classes_intersect_p (CC_REGS, class))
return GENERAL_REGS; return GENERAL_REGS;
return NO_REGS; return NO_REGS;
...@@ -3593,14 +3593,18 @@ void ...@@ -3593,14 +3593,18 @@ void
s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len) s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len)
{ {
rtx ccreg = gen_rtx_REG (CCUmode, CC_REGNUM); 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 (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256)
{ {
if (INTVAL (len) > 0) if (INTVAL (len) > 0)
{ {
emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (INTVAL (len) - 1))); emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (INTVAL (len) - 1)));
emit_move_insn (target, result); emit_insn (gen_cmpint (target, ccreg));
} }
else else
emit_move_insn (target, const0_rtx); emit_move_insn (target, const0_rtx);
...@@ -3608,7 +3612,7 @@ s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len) ...@@ -3608,7 +3612,7 @@ s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len)
else if (TARGET_MVCLE) else if (TARGET_MVCLE)
{ {
emit_insn (gen_cmpmem_long (op0, op1, convert_to_mode (Pmode, len, 1))); 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 else
{ {
...@@ -3675,7 +3679,7 @@ s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len) ...@@ -3675,7 +3679,7 @@ s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len)
convert_to_mode (Pmode, count, 1))); convert_to_mode (Pmode, count, 1)));
emit_label (end_label); emit_label (end_label);
emit_move_insn (target, result); emit_insn (gen_cmpint (target, ccreg));
} }
} }
......
...@@ -2276,33 +2276,76 @@ ...@@ -2276,33 +2276,76 @@
[(set_attr "length" "8") [(set_attr "length" "8")
(set_attr "type" "vs")]) (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") [(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); rtx result = gen_rtx_ASHIFTRT (SImode, operands[0], GEN_INT (30));
output_asm_insn ("jh\t.+12", operands); operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
output_asm_insn ("jl\t.+6", operands); operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
output_asm_insn ("sr\t%0,%0", operands); })
return "lcr\t%0,%0";
}
[(set_attr "length" "16")])
(define_insn "*cmpint_di" (define_insn_and_split "*cmpint_sign"
[(set (match_operand:DI 0 "register_operand" "=d") [(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" "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); rtx result = gen_rtx_ASHIFTRT (DImode, operands[0], GEN_INT (62));
output_asm_insn ("jh\t.+16", operands); operands[2] = SET_DEST (XVECEXP (PATTERN (curr_insn), 0, 0));
output_asm_insn ("jl\t.+8", operands); operands[3] = gen_rtx_COMPARE (GET_MODE (operands[2]), result, const0_rtx);
output_asm_insn ("sgr\t%0,%0", operands); })
return "lcgr\t%0,%0";
}
[(set_attr "length" "20")])
;; ;;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment