Commit 0a3bdf9d by Ulrich Weigand Committed by Ulrich Weigand

s390-modes.def (CCAPmode, CCANmode): New CC modes.

	* config/s390/s390-modes.def (CCAPmode, CCANmode): New CC modes.
	* config/s390/s390.c (s390_match_ccmode_set): Support new CC modes.
	(s390_select_ccmode): Likewise.
	(s390_branch_condition_mask): Likewise.
	(optimization_options): Do not set flag_branch_on_count.
	(s390_split_branches): Handle doloop branches.
	(s390_chunkify_pool): Likewise.
	* config/s390/s390.md ("*adddi3_imm_cc", "*addsi3_imm_cc"): New insns.
	("doloop_end"): New expander.
	("doolop_si", "*doloop_si_long", "doloop_di", "*doloop_di_long",
	associated splitters): New.

From-SVN: r57060
parent 81ea34e1
2002-09-12 Ulrich Weigand <uweigand@de.ibm.com>
* config/s390/s390-modes.def (CCAPmode, CCANmode): New CC modes.
* config/s390/s390.c (s390_match_ccmode_set): Support new CC modes.
(s390_select_ccmode): Likewise.
(s390_branch_condition_mask): Likewise.
(optimization_options): Do not set flag_branch_on_count.
(s390_split_branches): Handle doloop branches.
(s390_chunkify_pool): Likewise.
* config/s390/s390.md ("*adddi3_imm_cc", "*addsi3_imm_cc"): New insns.
("doloop_end"): New expander.
("doolop_si", "*doloop_si_long", "doloop_di", "*doloop_di_long",
associated splitters): New.
2002-09-11 Hartmut Penner <hpenner@de.ibm.com>
* fold-const.c (make_range): Only narrow to signed range if
......
......@@ -23,6 +23,8 @@ Boston, MA 02111-1307, USA. */
CC (CCZ)
CC (CCA)
CC (CCAP)
CC (CCAN)
CC (CCL)
CC (CCL1)
CC (CCL2)
......
......@@ -182,6 +182,12 @@ s390_match_ccmode_set (set, req_mode)
&& req_mode != CCSRmode && req_mode != CCURmode)
return 0;
break;
case CCAPmode:
case CCANmode:
if (req_mode != CCAmode)
return 0;
break;
default:
abort ();
......@@ -274,6 +280,9 @@ s390_select_ccmode (code, op0, op1)
{
case EQ:
case NE:
if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
&& CONST_OK_FOR_LETTER_P (INTVAL (XEXP (op0, 1)), 'K'))
return CCAPmode;
if (GET_CODE (op0) == PLUS || GET_CODE (op0) == MINUS
|| GET_CODE (op1) == NEG)
return CCLmode;
......@@ -306,6 +315,14 @@ s390_select_ccmode (code, op0, op1)
case LT:
case GE:
case GT:
if (GET_CODE (op0) == PLUS && GET_CODE (XEXP (op0, 1)) == CONST_INT
&& CONST_OK_FOR_LETTER_P (INTVAL (XEXP (op0, 1)), 'K'))
{
if (INTVAL (XEXP((op0), 1)) < 0)
return CCANmode;
else
return CCAPmode;
}
case UNORDERED:
case ORDERED:
case UNEQ:
......@@ -461,6 +478,34 @@ s390_branch_condition_mask (code)
}
break;
case CCAPmode:
switch (GET_CODE (code))
{
case EQ: return CC0;
case NE: return CC1 | CC2 | CC3;
case LT: return CC1 | CC3;
case GT: return CC2;
case LE: return CC0 | CC1 | CC3;
case GE: return CC0 | CC2;
default:
abort ();
}
break;
case CCANmode:
switch (GET_CODE (code))
{
case EQ: return CC0;
case NE: return CC1 | CC2 | CC3;
case LT: return CC1;
case GT: return CC2 | CC3;
case LE: return CC0 | CC1;
case GE: return CC0 | CC2 | CC3;
default:
abort ();
}
break;
case CCSmode:
switch (GET_CODE (code))
{
......@@ -758,11 +803,6 @@ optimization_options (level, size)
int level ATTRIBUTE_UNUSED;
int size ATTRIBUTE_UNUSED;
{
#ifdef HAVE_decrement_and_branch_on_count
/* When optimizing, enable use of BRCT instruction. */
if (level >= 1)
flag_branch_on_count_reg = 1;
#endif
}
void
......@@ -2605,12 +2645,8 @@ static void
s390_split_branches ()
{
rtx temp_reg = gen_rtx_REG (Pmode, RETURN_REGNUM);
rtx insn, pat, label, target, jump, tmp;
/* In 64-bit mode we can jump +- 4GB. */
if (TARGET_64BIT)
return;
rtx insn, pat, tmp, target;
rtx *label;
/* We need correct insn addresses. */
......@@ -2624,62 +2660,61 @@ s390_split_branches ()
continue;
pat = PATTERN (insn);
if (GET_CODE (pat) != SET)
if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) > 2)
pat = XVECEXP (pat, 0, 0);
if (GET_CODE (pat) != SET || SET_DEST (pat) != pc_rtx)
continue;
if (GET_CODE (SET_SRC (pat)) == LABEL_REF)
{
label = SET_SRC (pat);
label = &SET_SRC (pat);
}
else if (GET_CODE (SET_SRC (pat)) == IF_THEN_ELSE)
{
if (GET_CODE (XEXP (SET_SRC (pat), 1)) == LABEL_REF)
label = XEXP (SET_SRC (pat), 1);
label = &XEXP (SET_SRC (pat), 1);
else if (GET_CODE (XEXP (SET_SRC (pat), 2)) == LABEL_REF)
label = XEXP (SET_SRC (pat), 2);
label = &XEXP (SET_SRC (pat), 2);
else
continue;
}
else
continue;
if (get_attr_length (insn) == 4)
if (get_attr_length (insn) <= (TARGET_64BIT ? 6 : 4))
continue;
regs_ever_live[RETURN_REGNUM] = 1;
if (flag_pic)
if (TARGET_64BIT)
{
target = gen_rtx_UNSPEC (SImode, gen_rtvec (1, label), 100);
target = gen_rtx_CONST (SImode, target);
target = force_const_mem (SImode, target);
jump = gen_rtx_REG (Pmode, BASE_REGISTER);
jump = gen_rtx_PLUS (Pmode, jump, temp_reg);
tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, *label), insn);
INSN_ADDRESSES_NEW (tmp, -1);
target = temp_reg;
}
else
else if (!flag_pic)
{
target = force_const_mem (Pmode, label);
jump = temp_reg;
}
tmp = force_const_mem (Pmode, *label);
tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, tmp), insn);
INSN_ADDRESSES_NEW (tmp, -1);
if (GET_CODE (SET_SRC (pat)) == IF_THEN_ELSE)
target = temp_reg;
}
else
{
if (GET_CODE (XEXP (SET_SRC (pat), 1)) == LABEL_REF)
jump = gen_rtx_IF_THEN_ELSE (VOIDmode, XEXP (SET_SRC (pat), 0),
jump, pc_rtx);
else
jump = gen_rtx_IF_THEN_ELSE (VOIDmode, XEXP (SET_SRC (pat), 0),
pc_rtx, jump);
tmp = gen_rtx_UNSPEC (SImode, gen_rtvec (1, *label), 100);
tmp = gen_rtx_CONST (SImode, tmp);
tmp = force_const_mem (SImode, tmp);
tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, tmp), insn);
INSN_ADDRESSES_NEW (tmp, -1);
target = gen_rtx_REG (Pmode, BASE_REGISTER);
target = gen_rtx_PLUS (Pmode, target, temp_reg);
}
tmp = emit_insn_before (gen_rtx_SET (Pmode, temp_reg, target), insn);
INSN_ADDRESSES_NEW (tmp, -1);
tmp = emit_jump_insn_before (gen_rtx_SET (VOIDmode, pc_rtx, jump), insn);
INSN_ADDRESSES_NEW (tmp, -1);
remove_insn (insn);
insn = tmp;
if (!validate_change (insn, label, target, 0))
abort ();
}
}
......@@ -3177,6 +3212,9 @@ s390_chunkify_pool ()
else if (GET_CODE (insn) == JUMP_INSN)
{
rtx pat = PATTERN (insn);
if (GET_CODE (pat) == PARALLEL && XVECLEN (pat, 0) > 2)
pat = XVECEXP (pat, 0, 0);
if (GET_CODE (pat) == SET)
{
rtx label = 0;
......
......@@ -3080,6 +3080,20 @@
[(set_attr "op_type" "RRE,RXE")
(set_attr "atype" "reg,mem")])
(define_insn "*adddi3_imm_cc"
[(set (reg 33)
(compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "0")
(match_operand:DI 2 "const_int_operand" "K"))
(const_int 0)))
(set (match_operand:DI 0 "register_operand" "=d")
(plus:DI (match_dup 1) (match_dup 2)))]
"TARGET_64BIT
&& s390_match_ccmode (insn, CCAmode)
&& CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
"aghi\\t%0,%h2"
[(set_attr "op_type" "RI")
(set_attr "atype" "reg")])
(define_insn "*adddi3_cc"
[(set (reg 33)
(compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
......@@ -3210,6 +3224,19 @@
(set_attr "atype" "mem")
(set_attr "type" "la")])
(define_insn "*addsi3_imm_cc"
[(set (reg 33)
(compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "0")
(match_operand:SI 2 "const_int_operand" "K"))
(const_int 0)))
(set (match_operand:SI 0 "register_operand" "=d")
(plus:SI (match_dup 1) (match_dup 2)))]
"s390_match_ccmode (insn, CCAmode)
&& CONST_OK_FOR_LETTER_P (INTVAL (operands[2]), 'K')"
"ahi\\t%0,%h2"
[(set_attr "op_type" "RI")
(set_attr "atype" "reg")])
(define_insn "*addsi3_carry1_cc"
[(set (reg 33)
(compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
......@@ -5945,52 +5972,184 @@
;;
;;- Subtract one and jump if not zero.
;;- Loop instructions.
;;
;; This is all complicated by the fact that since this is a jump insn
;; we must handle our own output reloads.
(define_expand "doloop_end"
[(use (match_operand 0 "" "")) ; loop pseudo
(use (match_operand 1 "" "")) ; iterations; zero if unknown
(use (match_operand 2 "" "")) ; max iterations
(use (match_operand 3 "" "")) ; loop level
(use (match_operand 4 "" ""))] ; label
""
"
{
if (GET_MODE (operands[0]) == SImode)
emit_jump_insn (gen_doloop_si (operands[4], operands[0], operands[0]));
else if (GET_MODE (operands[0]) == DImode && TARGET_64BIT)
emit_jump_insn (gen_doloop_di (operands[4], operands[0], operands[0]));
else
FAIL;
DONE;
}")
(define_insn "doloop_si"
[(set (pc)
(if_then_else
(ne (match_operand:SI 1 "register_operand" "d,d")
(const_int 1))
(label_ref (match_operand 0 "" ""))
(pc)))
(set (match_operand:SI 2 "register_operand" "=1,?*m*d")
(plus:SI (match_dup 1) (const_int -1)))
(clobber (match_scratch:SI 3 "=X,&d"))
(clobber (reg:CC 33))]
""
"*
{
if (which_alternative != 0)
return \"#\";
else if (get_attr_length (insn) == 4)
return \"brct\\t%1,%l0\";
else
abort ();
}"
[(set_attr "op_type" "RI")
(set (attr "length")
(cond [(lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
(const_int 4)
(ne (symbol_ref "TARGET_64BIT") (const_int 0))
(const_int 10)
(ne (symbol_ref "s390_pool_overflow") (const_int 0))
(if_then_else (eq (symbol_ref "flag_pic") (const_int 0))
(const_int 12) (const_int 14))
(eq (symbol_ref "flag_pic") (const_int 0))
(const_int 6)] (const_int 8)))])
(define_insn "*doloop_si_long"
[(set (pc)
(if_then_else
(ne (match_operand:SI 1 "register_operand" "d,d")
(const_int 1))
(match_operand 0 "address_operand" "p,p")
(pc)))
(set (match_operand:SI 2 "register_operand" "=1,?*m*d")
(plus:SI (match_dup 1) (const_int -1)))
(clobber (match_scratch:SI 3 "=X,&d"))
(clobber (reg:CC 33))]
""
"*
{
if (get_attr_op_type (insn) == OP_TYPE_RR)
return \"bctr\\t%0\";
else
return \"bct\\t%a0\";
}"
[(set (attr "op_type")
(if_then_else (match_operand 0 "register_operand" "")
(const_string "RR") (const_string "RX")))
(set_attr "atype" "mem")])
;(define_expand "decrement_and_branch_on_count"
; [(use (match_operand 0 "register_operand" ""))
; (use (label_ref (match_operand 1 "" "")))]
; ""
; "
;{
;/* if (TARGET_64BIT)
; emit_jump_insn (gen_brctdi (operands[0], operands[1]));
; else */
; emit_jump_insn (gen_brctsi (operands[0], operands[1]));
; DONE;
;}")
;
;(define_insn "brctsi"
; [(set (pc)
; (if_then_else
; (ne (match_operand:SI 0 "register_operand" "+a")
; (const_int 1))
; (label_ref (match_operand 1 "" ""))
; (pc)))
; (set (match_dup 0)
; (plus:SI (match_dup 0) (const_int -1)))]
; ""
; "brct\\t%0,%l1"
; [(set_attr "op_type" "RI")
; (set_attr "type" "branch")]
;)
;
;(define_insn "ibrctsi"
; [(set (pc)
; (if_then_else
; (eq (match_operand:SI 0 "register_operand" "+a")
; (const_int 1))
; (pc)
; (label_ref (match_operand 1 "" ""))))
; (set (match_dup 0)
; (plus:SI (match_dup 0) (const_int -1)))]
; ""
; "brct\\t%0,%l1"
; [(set_attr "op_type" "RI")
; (set_attr "type" "branch")]
;)
(define_split
[(set (pc)
(if_then_else (ne (match_operand:SI 1 "register_operand" "")
(const_int 1))
(match_operand 0 "" "")
(pc)))
(set (match_operand:SI 2 "nonimmediate_operand" "")
(plus:SI (match_dup 1) (const_int -1)))
(clobber (match_scratch:SI 3 ""))
(clobber (reg:CC 33))]
"reload_completed
&& (! REG_P (operands[2])
|| ! rtx_equal_p (operands[1], operands[2]))"
[(set (match_dup 3) (match_dup 1))
(parallel [(set (reg:CCAN 33)
(compare:CCAN (plus:SI (match_dup 3) (const_int -1))
(const_int 0)))
(set (match_dup 3) (plus:SI (match_dup 3) (const_int -1)))])
(set (match_dup 2) (match_dup 3))
(set (pc) (if_then_else (ne (reg:CCAN 33) (const_int 0))
(match_dup 0)
(pc)))]
"")
(define_insn "doloop_di"
[(set (pc)
(if_then_else
(ne (match_operand:DI 1 "register_operand" "d,d")
(const_int 1))
(label_ref (match_operand 0 "" ""))
(pc)))
(set (match_operand:DI 2 "register_operand" "=1,?*m*r")
(plus:DI (match_dup 1) (const_int -1)))
(clobber (match_scratch:DI 3 "=X,&d"))
(clobber (reg:CC 33))]
"TARGET_64BIT"
"*
{
if (which_alternative != 0)
return \"#\";
else if (get_attr_length (insn) == 4)
return \"brctg\\t%1,%l0\";
else
abort ();
}"
[(set_attr "op_type" "RI")
(set (attr "length")
(if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
(const_int 4) (const_int 12)))])
(define_insn "*doloop_di_long"
[(set (pc)
(if_then_else
(ne (match_operand:DI 1 "register_operand" "d,d")
(const_int 1))
(match_operand 0 "address_operand" "p,p")
(pc)))
(set (match_operand:DI 2 "register_operand" "=1,?*m*d")
(plus:DI (match_dup 1) (const_int -1)))
(clobber (match_scratch:DI 3 "=X,&d"))
(clobber (reg:CC 33))]
""
"*
{
if (get_attr_op_type (insn) == OP_TYPE_RRE)
return \"bctgr\\t%0\";
else
return \"bctg\\t%a0\";
}"
[(set (attr "op_type")
(if_then_else (match_operand 0 "register_operand" "")
(const_string "RRE") (const_string "RXE")))
(set_attr "atype" "mem")])
(define_split
[(set (pc)
(if_then_else (ne (match_operand:DI 1 "register_operand" "")
(const_int 1))
(match_operand 0 "" "")
(pc)))
(set (match_operand:DI 2 "nonimmediate_operand" "")
(plus:DI (match_dup 1) (const_int -1)))
(clobber (match_scratch:DI 3 ""))
(clobber (reg:CC 33))]
"reload_completed
&& (! REG_P (operands[2])
|| ! rtx_equal_p (operands[1], operands[2]))"
[(set (match_dup 3) (match_dup 1))
(parallel [(set (reg:CCAN 33)
(compare:CCAN (plus:DI (match_dup 3) (const_int -1))
(const_int 0)))
(set (match_dup 3) (plus:DI (match_dup 3) (const_int -1)))])
(set (match_dup 2) (match_dup 3))
(set (pc) (if_then_else (ne (reg:CCAN 33) (const_int 0))
(match_dup 0)
(pc)))]
"")
;;
;;- Unconditional jump instructions.
......
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