Commit 8d946ecc by Eric Botcazou Committed by Eric Botcazou

visium-modes.def (CC_NOOV): Rename into...

	* config/visium/visium-modes.def (CC_NOOV): Rename into...
	(CCNZ): ...this.
	(CC_BTST): Rename into...
	(CCC): ...this.
	* config/visium/predicates.md (real_add_operand): New.
	(visium_btst_operator): Rename into...
	(visium_equality_comparison_operator): ...this.
	(visium_noov_operator): Rename into...
	(visium_nz_comparison_operator): ...this.
	(visium_c_comparison_operator): New.
	(visium_branch_operator): Adjust and deal with all CC modes.
	* config/visium/visium.c (visium_adjust_cost): Adjust.
	(visium_split_double_add): Use the *_set_carry patterns.
	(visium_select_cc_mode): Add support for CCC mode and adjust.
	(output_cbranch): Adjust and use the carry-based operators for
	floating-point comparisons.
	* config/visium/visium.md (flags_subst_arith): Adjust.
	(addsi3_insn_set_carry): New instruction.
	(subsi3_insn_set_carry): Likewise.
	(negsi2_insn_set_carry): Likewise.
	(btst): Adjust.
	(cmp<mode>_sne): Likewise.
	(cbranch<mode>4): Use ordered_comparison_operator.
	(cbranch<mode>4_insn): Likewise.
	(cbranchsi4_btst_insn): Adjust.

From-SVN: r240969
parent 431e31a9
2016-10-11 Eric Botcazou <ebotcazou@adacore.com>
* config/visium/visium-modes.def (CC_NOOV): Rename into...
(CCNZ): ...this.
(CC_BTST): Rename into...
(CCC): ...this.
* config/visium/predicates.md (real_add_operand): New.
(visium_btst_operator): Rename into...
(visium_equality_comparison_operator): ...this.
(visium_noov_operator): Rename into...
(visium_nz_comparison_operator): ...this.
(visium_c_comparison_operator): New.
(visium_branch_operator): Adjust and deal with all CC modes.
* config/visium/visium.c (visium_adjust_cost): Adjust.
(visium_split_double_add): Use the *_set_carry patterns.
(visium_select_cc_mode): Add support for CCC mode and adjust.
(output_cbranch): Adjust and use the carry-based operators for
floating-point comparisons.
* config/visium/visium.md (flags_subst_arith): Adjust.
(addsi3_insn_set_carry): New instruction.
(subsi3_insn_set_carry): Likewise.
(negsi2_insn_set_carry): Likewise.
(btst): Adjust.
(cmp<mode>_sne): Likewise.
(cbranch<mode>4): Use ordered_comparison_operator.
(cbranch<mode>4_insn): Likewise.
(cbranchsi4_btst_insn): Adjust.
2016-10-11 Tom de Vries <tom@codesourcery.com> 2016-10-11 Tom de Vries <tom@codesourcery.com>
PR middle-end/77558 PR middle-end/77558
......
...@@ -112,6 +112,13 @@ ...@@ -112,6 +112,13 @@
(and (match_code "const_int") (and (match_code "const_int")
(match_test ("INTVAL (op) >= -65535 && INTVAL (op) <= 65535"))))) (match_test ("INTVAL (op) >= -65535 && INTVAL (op) <= 65535")))))
;; Return true if OP can be used as the second operand in a 32-bit or 64-bit
;; add or subtract instruction directly, i.e. without the reverse trick.
(define_predicate "real_add_operand"
(ior (match_operand 0 "gpc_reg_operand")
(and (match_code "const_int")
(match_test ("INTVAL (op) >= 0 && INTVAL (op) <= 65535")))))
;; Return true if OP is (or could be) outside the range 0 .. 65535, which is ;; Return true if OP is (or could be) outside the range 0 .. 65535, which is
;; the range of the immediate operands, but accept -1 for NOT. ;; the range of the immediate operands, but accept -1 for NOT.
(define_predicate "large_immediate_operand" (define_predicate "large_immediate_operand"
...@@ -119,33 +126,41 @@ ...@@ -119,33 +126,41 @@
(and (match_code "const_int") (and (match_code "const_int")
(match_test ("INTVAL (op) < -1 || INTVAL (op) > 65535"))))) (match_test ("INTVAL (op) < -1 || INTVAL (op) > 65535")))))
;; Return true if OP is an equality comparison operator.
(define_predicate "visium_equality_comparison_operator"
(match_code "eq,ne"))
;; Return true if OP is a valid comparison operator for CCNZmode.
(define_special_predicate "visium_nz_comparison_operator"
(match_code "eq,ne,lt,ge"))
;; Return true if OP is a valid comparison operator for CCCmode.
(define_special_predicate "visium_c_comparison_operator"
(match_code "eq,ne,ltu,geu"))
;; Return true if OP is a valid FP comparison operator. ;; Return true if OP is a valid FP comparison operator.
(define_predicate "visium_fp_comparison_operator" (define_predicate "visium_fp_comparison_operator"
(match_code "eq,ne,ordered,unordered,unlt,unle,ungt,unge,lt,le,gt,ge")) (match_code "eq,ne,ordered,unordered,unlt,unle,ungt,unge,lt,le,gt,ge"))
;; Return true if OP is a valid comparison operator for CC_BTSTmode.
(define_special_predicate "visium_btst_operator"
(match_code "eq,ne"))
;; Return true if OP is a valid comparison operator for CC_NOOVmode.
(define_special_predicate "visium_noov_operator"
(match_code "eq,ne,ge,lt"))
;; Return true if OP is a valid comparison operator for a branch. This allows ;; Return true if OP is a valid comparison operator for a branch. This allows
;; the use of MATCH_OPERATOR to recognize all the branch insns. ;; the use of MATCH_OPERATOR to recognize all the branch insns.
(define_predicate "visium_branch_operator" (define_predicate "visium_branch_operator"
(match_operand 0 "comparison_operator") (match_operand 0 "comparison_operator")
{ {
enum rtx_code code = GET_CODE (op); switch (GET_MODE (XEXP (op, 0)))
/* These 2 comparison codes are not supported. */ {
if (code == UNEQ || code == LTGT) case CCmode:
return false; return ordered_comparison_operator (op, mode);
enum machine_mode cc_mode = GET_MODE (XEXP (op, 0)); case CCNZmode:
if (cc_mode == CC_NOOVmode) return visium_nz_comparison_operator (op, mode);
return visium_noov_operator (op, mode); case CCCmode:
if (cc_mode == CC_BTSTmode) return visium_c_comparison_operator (op, mode);
return visium_btst_operator (op, mode); case CCFPmode:
return true; case CCFPEmode:
return visium_fp_comparison_operator (op, mode);
default:
return false;
}
}) })
;; Return true if OP is a valid comparison operator for an integer cstore. ;; Return true if OP is a valid comparison operator for an integer cstore.
......
...@@ -19,19 +19,22 @@ along with GCC; see the file COPYING3. If not see ...@@ -19,19 +19,22 @@ along with GCC; see the file COPYING3. If not see
/* Add any extra modes needed to represent the condition code. /* Add any extra modes needed to represent the condition code.
On the Visium, we have a "no-overflow" mode which is used when arithmetic We have a CCNZ mode which is used for implicit comparisons with zero when
instructions set the condition code. Different branches are used in this arithmetic instructions set the condition code. Only the N and Z flags
case for some operations. are valid in this mode, which means that only the =,!= and <,>= operators
can be used in conjunction with it.
We also have a "bit-test" mode which is used when the bit-test instruction We also have a CCCmode which is used by the arithmetic instructions when
sets the condition code. they explicitly set the C flag (unsigned overflow) and by the bit-test
instruction. Only the =,!= and unsigned <,>= operators can be used in
conjunction with it.
We also have two modes to indicate that the condition code is set by the We also have two modes to indicate that the condition code is set by the
the floating-point unit. One for comparisons which generate an exception the floating-point unit. One for comparisons which generate an exception
if the result is unordered (CCFPEmode) and one for comparisons which never if the result is unordered (CCFPEmode) and one for comparisons which never
generate such an exception (CCFPmode). */ generate such an exception (CCFPmode). */
CC_MODE (CC_NOOV); CC_MODE (CCNZ);
CC_MODE (CC_BTST); CC_MODE (CCC);
CC_MODE (CCFP); CC_MODE (CCFP);
CC_MODE (CCFPE); CC_MODE (CCFPE);
...@@ -561,11 +561,12 @@ visium_adjust_cost (rtx_insn *insn, int dep_type, rtx_insn *dep_insn, int cost, ...@@ -561,11 +561,12 @@ visium_adjust_cost (rtx_insn *insn, int dep_type, rtx_insn *dep_insn, int cost,
/* The logical instructions use CCmode and thus work with any /* The logical instructions use CCmode and thus work with any
comparison operator, whereas the arithmetic instructions use comparison operator, whereas the arithmetic instructions use
CC_NOOVmode and thus work with only a small subset. */ CCNZmode and thus work with only a small subset. */
if (dep_attr_type == TYPE_LOGIC if (dep_attr_type == TYPE_LOGIC
|| (dep_attr_type == TYPE_ARITH || (dep_attr_type == TYPE_ARITH
&& visium_noov_operator (XEXP (src, 0), && visium_nz_comparison_operator (XEXP (src, 0),
GET_MODE (XEXP (src, 0))))) GET_MODE
(XEXP (src, 0)))))
return 0; return 0;
} }
} }
...@@ -2113,16 +2114,12 @@ visium_split_double_add (enum rtx_code code, rtx op0, rtx op1, rtx op2) ...@@ -2113,16 +2114,12 @@ visium_split_double_add (enum rtx_code code, rtx op0, rtx op1, rtx op2)
op8 = gen_highpart (SImode, op2); op8 = gen_highpart (SImode, op2);
} }
/* This is the {add,sub,neg}si3_insn_set_flags pattern. */
if (op4 == const0_rtx) if (op4 == const0_rtx)
x = gen_rtx_NEG (SImode, op5); pat = gen_negsi2_insn_set_carry (op3, op5);
else if (code == MINUS)
pat = gen_subsi3_insn_set_carry (op3, op4, op5);
else else
x = gen_rtx_fmt_ee (code, SImode, op4, op5); pat = gen_addsi3_insn_set_carry (op3, op4, op5);
pat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
XVECEXP (pat, 0, 0) = gen_rtx_SET (op3, x);
flags = gen_rtx_REG (CC_NOOVmode, FLAGS_REGNUM);
x = gen_rtx_COMPARE (CC_NOOVmode, shallow_copy_rtx (x), const0_rtx);
XVECEXP (pat, 0, 1) = gen_rtx_SET (flags, x);
emit_insn (pat); emit_insn (pat);
/* This is the plus_[plus_]sltu_flags or minus_[minus_]sltu_flags pattern. */ /* This is the plus_[plus_]sltu_flags or minus_[minus_]sltu_flags pattern. */
...@@ -2130,6 +2127,7 @@ visium_split_double_add (enum rtx_code code, rtx op0, rtx op1, rtx op2) ...@@ -2130,6 +2127,7 @@ visium_split_double_add (enum rtx_code code, rtx op0, rtx op1, rtx op2)
x = op7; x = op7;
else else
x = gen_rtx_fmt_ee (code, SImode, op7, op8); x = gen_rtx_fmt_ee (code, SImode, op7, op8);
flags = gen_rtx_REG (CCCmode, FLAGS_REGNUM);
x = gen_rtx_fmt_ee (code, SImode, x, gen_rtx_LTU (SImode, flags, const0_rtx)); x = gen_rtx_fmt_ee (code, SImode, x, gen_rtx_LTU (SImode, flags, const0_rtx));
pat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2)); pat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
XVECEXP (pat, 0, 0) = gen_rtx_SET (op6, x); XVECEXP (pat, 0, 0) = gen_rtx_SET (op6, x);
...@@ -2814,6 +2812,16 @@ visium_select_cc_mode (enum rtx_code code, rtx op0, rtx op1) ...@@ -2814,6 +2812,16 @@ visium_select_cc_mode (enum rtx_code code, rtx op0, rtx op1)
} }
} }
/* This is for the cmp<mode>_sne pattern. */
if (op1 == constm1_rtx)
return CCCmode;
/* This is for the add<mode>3_insn_set_carry pattern. */
if ((code == LTU || code == GEU)
&& GET_CODE (op0) == PLUS
&& rtx_equal_p (XEXP (op0, 0), op1))
return CCCmode;
if (op1 != const0_rtx) if (op1 != const0_rtx)
return CCmode; return CCmode;
...@@ -2825,17 +2833,17 @@ visium_select_cc_mode (enum rtx_code code, rtx op0, rtx op1) ...@@ -2825,17 +2833,17 @@ visium_select_cc_mode (enum rtx_code code, rtx op0, rtx op1)
case ASHIFT: case ASHIFT:
case LTU: case LTU:
case LT: case LT:
/* The V flag may be set differently from a COMPARE with zero. /* The C and V flags may be set differently from a COMPARE with zero.
The consequence is that a comparison operator testing V must The consequence is that a comparison operator testing C or V must
be turned into another operator not testing V and yielding be turned into another operator not testing C or V and yielding
the same result for a comparison with zero. That's possible the same result for a comparison with zero. That's possible for
for GE/LT which become NC/NS respectively, but not for GT/LE GE/LT which become NC/NS respectively, but not for GT/LE for which
for which the altered operator doesn't exist on the Visium. */ the altered operator doesn't exist on the Visium. */
return CC_NOOVmode; return CCNZmode;
case ZERO_EXTRACT: case ZERO_EXTRACT:
/* This is a btst, the result is in C instead of Z. */ /* This is a btst, the result is in C instead of Z. */
return CC_BTSTmode; return CCCmode;
case CONST_INT: case CONST_INT:
/* This is a degenerate case, typically an uninitialized variable. */ /* This is a degenerate case, typically an uninitialized variable. */
...@@ -3077,21 +3085,21 @@ output_cbranch (rtx label, enum rtx_code code, enum machine_mode cc_mode, ...@@ -3077,21 +3085,21 @@ output_cbranch (rtx label, enum rtx_code code, enum machine_mode cc_mode,
switch (code) switch (code)
{ {
case NE: case NE:
if (cc_mode == CC_BTSTmode) if (cc_mode == CCCmode)
cond = "cs"; cond = "cs";
else else
cond = "ne"; cond = "ne";
break; break;
case EQ: case EQ:
if (cc_mode == CC_BTSTmode) if (cc_mode == CCCmode)
cond = "cc"; cond = "cc";
else else
cond = "eq"; cond = "eq";
break; break;
case GE: case GE:
if (cc_mode == CC_NOOVmode) if (cc_mode == CCNZmode)
cond = "nc"; cond = "nc";
else else
cond = "ge"; cond = "ge";
...@@ -3110,8 +3118,8 @@ output_cbranch (rtx label, enum rtx_code code, enum machine_mode cc_mode, ...@@ -3110,8 +3118,8 @@ output_cbranch (rtx label, enum rtx_code code, enum machine_mode cc_mode,
case LT: case LT:
if (cc_mode == CCFPmode || cc_mode == CCFPEmode) if (cc_mode == CCFPmode || cc_mode == CCFPEmode)
cond = "ns"; cond = "cs"; /* or "ns" */
else if (cc_mode == CC_NOOVmode) else if (cc_mode == CCNZmode)
cond = "ns"; cond = "ns";
else else
cond = "lt"; cond = "lt";
...@@ -3142,7 +3150,7 @@ output_cbranch (rtx label, enum rtx_code code, enum machine_mode cc_mode, ...@@ -3142,7 +3150,7 @@ output_cbranch (rtx label, enum rtx_code code, enum machine_mode cc_mode,
break; break;
case UNGE: case UNGE:
cond = "nc"; cond = "cc"; /* or "nc" */
break; break;
case UNGT: case UNGT:
......
...@@ -257,8 +257,8 @@ ...@@ -257,8 +257,8 @@
(clobber (reg:CC R_FLAGS))] (clobber (reg:CC R_FLAGS))]
"" ""
[(set (match_dup 0) (match_dup 1)) [(set (match_dup 0) (match_dup 1))
(set (reg:CC_NOOV R_FLAGS) (set (reg:CCNZ R_FLAGS)
(compare:CC_NOOV (match_dup 1) (const_int 0)))]) (compare:CCNZ (match_dup 1) (const_int 0)))])
(define_subst_attr "subst_arith" "flags_subst_arith" "_flags" "_set_flags") (define_subst_attr "subst_arith" "flags_subst_arith" "_flags" "_set_flags")
...@@ -809,6 +809,19 @@ ...@@ -809,6 +809,19 @@
addi %0,%2" addi %0,%2"
[(set_attr "type" "arith")]) [(set_attr "type" "arith")])
(define_insn "addsi3_insn_set_carry"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(plus:SI (match_operand:SI 1 "register_operand" "%r,0")
(match_operand:SI 2 "real_add_operand" " r,J")))
(set (reg:CCC R_FLAGS)
(compare:CCC (plus:SI (match_dup 1) (match_dup 2))
(match_dup 1)))]
"reload_completed"
"@
add.l %0,%1,%2
addi %0,%2"
[(set_attr "type" "arith")])
(define_expand "adddi3" (define_expand "adddi3"
[(set (match_operand:DI 0 "register_operand" "") [(set (match_operand:DI 0 "register_operand" "")
(plus:DI (match_operand:DI 1 "register_operand" "") (plus:DI (match_operand:DI 1 "register_operand" "")
...@@ -948,6 +961,18 @@ ...@@ -948,6 +961,18 @@
subi %0,%2" subi %0,%2"
[(set_attr "type" "arith")]) [(set_attr "type" "arith")])
(define_insn "subsi3_insn_set_carry"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(minus:SI (match_operand:SI 1 "register_operand" " r,0")
(match_operand:SI 2 "real_add_operand" " r,J")))
(set (reg:CC R_FLAGS)
(compare:CC (match_dup 1) (match_dup 2)))]
"reload_completed"
"@
sub.l %0,%r1,%2
subi %0,%2"
[(set_attr "type" "arith")])
(define_expand "subdi3" (define_expand "subdi3"
[(set (match_operand:DI 0 "register_operand" "") [(set (match_operand:DI 0 "register_operand" "")
(minus:DI (match_operand:DI 1 "register_operand" "") (minus:DI (match_operand:DI 1 "register_operand" "")
...@@ -1041,6 +1066,15 @@ ...@@ -1041,6 +1066,15 @@
"sub<s> %0,r0,%1" "sub<s> %0,r0,%1"
[(set_attr "type" "arith")]) [(set_attr "type" "arith")])
(define_insn "negsi2_insn_set_carry"
[(set (match_operand:SI 0 "register_operand" "=r")
(neg:SI (match_operand:SI 1 "register_operand" "r")))
(set (reg:CCC R_FLAGS)
(compare:CCC (not:SI (match_dup 1)) (const_int -1)))]
"reload_completed"
"sub.l %0,r0,%1"
[(set_attr "type" "arith")])
(define_expand "negdi2" (define_expand "negdi2"
[(set (match_operand:DI 0 "register_operand" "") [(set (match_operand:DI 0 "register_operand" "")
(neg:DI (match_operand:DI 1 "register_operand" "")))] (neg:DI (match_operand:DI 1 "register_operand" "")))]
...@@ -1803,12 +1837,12 @@ ...@@ -1803,12 +1837,12 @@
; BITS_BIG_ENDIAN is defined to 1 so operand #1 counts from the MSB. ; BITS_BIG_ENDIAN is defined to 1 so operand #1 counts from the MSB.
(define_insn "*btst" (define_insn "*btst"
[(set (reg:CC_BTST R_FLAGS) [(set (reg:CCC R_FLAGS)
(compare:CC_BTST (zero_extract:SI (compare:CCC (zero_extract:SI
(match_operand:SI 0 "register_operand" "r") (match_operand:SI 0 "register_operand" "r")
(const_int 1) (const_int 1)
(match_operand:QI 1 "const_shift_operand" "K")) (match_operand:QI 1 "const_shift_operand" "K"))
(const_int 0)))] (const_int 0)))]
"reload_completed" "reload_completed"
"lsr.l r0,%0,32-%1" "lsr.l r0,%0,32-%1"
[(set_attr "type" "logic")]) [(set_attr "type" "logic")])
...@@ -1832,9 +1866,9 @@ ...@@ -1832,9 +1866,9 @@
[(set_attr "type" "cmp")]) [(set_attr "type" "cmp")])
(define_insn "*cmp<mode>_sne" (define_insn "*cmp<mode>_sne"
[(set (reg:CC R_FLAGS) [(set (reg:CCC R_FLAGS)
(compare:CC (not:I (match_operand:I 0 "register_operand" "r")) (compare:CCC (not:I (match_operand:I 0 "register_operand" "r"))
(const_int -1)))] (const_int -1)))]
"reload_completed" "reload_completed"
"cmp<s> r0,%0" "cmp<s> r0,%0"
[(set_attr "type" "cmp")]) [(set_attr "type" "cmp")])
...@@ -2065,7 +2099,7 @@ ...@@ -2065,7 +2099,7 @@
(define_expand "cbranch<mode>4" (define_expand "cbranch<mode>4"
[(set (pc) [(set (pc)
(if_then_else (match_operator 0 "comparison_operator" (if_then_else (match_operator 0 "ordered_comparison_operator"
[(match_operand:I 1 "register_operand") [(match_operand:I 1 "register_operand")
(match_operand:I 2 "reg_or_0_operand")]) (match_operand:I 2 "reg_or_0_operand")])
(label_ref (match_operand 3 "")) (label_ref (match_operand 3 ""))
...@@ -2075,7 +2109,7 @@ ...@@ -2075,7 +2109,7 @@
(define_insn_and_split "*cbranch<mode>4_insn" (define_insn_and_split "*cbranch<mode>4_insn"
[(set (pc) [(set (pc)
(if_then_else (match_operator 0 "comparison_operator" (if_then_else (match_operator 0 "ordered_comparison_operator"
[(match_operand:I 1 "register_operand" "r") [(match_operand:I 1 "register_operand" "r")
(match_operand:I 2 "reg_or_0_operand" "rO")]) (match_operand:I 2 "reg_or_0_operand" "rO")])
(label_ref (match_operand 3 "")) (label_ref (match_operand 3 ""))
...@@ -2093,7 +2127,7 @@ ...@@ -2093,7 +2127,7 @@
(define_insn_and_split "*cbranchsi4_btst_insn" (define_insn_and_split "*cbranchsi4_btst_insn"
[(set (pc) [(set (pc)
(if_then_else (match_operator 0 "visium_btst_operator" (if_then_else (match_operator 0 "visium_equality_comparison_operator"
[(zero_extract:SI [(zero_extract:SI
(match_operand:SI 1 "register_operand" "r") (match_operand:SI 1 "register_operand" "r")
(const_int 1) (const_int 1)
......
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