v850.md (cbranchsf4): New pattern.

* config/v850/v850.md (cbranchsf4): New pattern.
	(cstoresf4): New pattern.
	(cbranchdf4): New pattern.
	(cstoredf4): New pattern.
	(movsicc): Disallow floating point comparisons.
	(cmpsf_le_insn): Fix order of operators.
	(cmpsf_lt_insn): Likewise.
	(cmpsf_eq_insn): Likewise.
	(cmpdf_le_insn): Likewise.
	(cmpdf_lt_insn): Likewise.
	(cmpdf_eq_insn): Likewise.
	(cmpsf_ge_insn): Use LE comparison.
	(cmpdf_ge_insn): Likewise.
	(cmpsf_gt_insn): Use LT comparison.
	(cmpdf_gt_insn): Likewise.
	(cmpsf_ne_insn): Delete pattern.
	(cmpdf_ne_insn): Delete pattern.
	* config/v850/v850.c (v850_gen_float_compare): Use
	gen_cmpdf_eq_insn for NE comparison.
	(v850_float_z_comparison_operator)
	(v850_float_nz_comparison_operator): Move from here ...
	* config/v850/predicates.md: ... to here.  Move GT and GE
	comparisons into v850_float_z_comparison_operator.
	* config/v850/v850-protos.h (v850_float_z_comparison_operator):
	Delete prototype.
	(v850_float_nz_comparison_operator): Likewise.

From-SVN: r195053
This commit is contained in:
Nguyen Duy Dat 2013-01-09 15:07:08 +00:00 committed by Nick Clifton
parent 458752def1
commit 3cd232b5aa
5 changed files with 233 additions and 103 deletions

View File

@ -1,3 +1,33 @@
2013-01-09 Nguyen Duy Dat
Nick Clifton <nickc@redhat.com>
* config/v850/v850.md (cbranchsf4): New pattern.
(cstoresf4): New pattern.
(cbranchdf4): New pattern.
(cstoredf4): New pattern.
(movsicc): Disallow floating point comparisons.
(cmpsf_le_insn): Fix order of operators.
(cmpsf_lt_insn): Likewise.
(cmpsf_eq_insn): Likewise.
(cmpdf_le_insn): Likewise.
(cmpdf_lt_insn): Likewise.
(cmpdf_eq_insn): Likewise.
(cmpsf_ge_insn): Use LE comparison.
(cmpdf_ge_insn): Likewise.
(cmpsf_gt_insn): Use LT comparison.
(cmpdf_gt_insn): Likewise.
(cmpsf_ne_insn): Delete pattern.
(cmpdf_ne_insn): Delete pattern.
* config/v850/v850.c (v850_gen_float_compare): Use
gen_cmpdf_eq_insn for NE comparison.
(v850_float_z_comparison_operator)
(v850_float_nz_comparison_operator): Move from here ...
* config/v850/predicates.md: ... to here. Move GT and GE
comparisons into v850_float_z_comparison_operator.
* config/v850/v850-protos.h (v850_float_z_comparison_operator):
Delete prototype.
(v850_float_nz_comparison_operator): Likewise.
2013-01-09 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
* config/pa/pa.c (pa_emit_move_sequence): Replace calls to gen_insv

View File

@ -497,3 +497,68 @@
return op == CONST0_RTX(mode);
})
;; Return true if the floating point comparison operation
;; given produces a canonical answer.
(define_predicate "v850_float_z_comparison_operator"
(match_code "lt,le,eq,gt,ge")
{
enum rtx_code code = GET_CODE (op);
if (GET_RTX_CLASS (code) != RTX_COMPARE
&& GET_RTX_CLASS (code) != RTX_COMM_COMPARE)
return 0;
if (mode != GET_MODE (op) && mode != VOIDmode)
return 0;
if ((GET_CODE (XEXP (op, 0)) != REG
|| REGNO (XEXP (op, 0)) != CC_REGNUM)
|| XEXP (op, 1) != const0_rtx)
return 0;
if (GET_MODE (XEXP (op, 0)) == CC_FPU_LTmode)
return code == LT;
if (GET_MODE (XEXP (op, 0)) == CC_FPU_LEmode)
return code == LE;
if (GET_MODE (XEXP (op, 0)) == CC_FPU_EQmode)
return code == EQ;
if (GET_MODE (XEXP (op, 0)) == CC_FPU_GTmode)
return code == GT;
if (GET_MODE (XEXP (op, 0)) == CC_FPU_GEmode)
return code == GE;
/* Note we do not accept CC_FPU_NEmode here. See
v850_float_nz_comparison for the reason why. */
return 0;
})
;; Return true if the floating point comparison operation
;; given produces an inverted answer.
(define_predicate "v850_float_nz_comparison_operator"
(match_code "ne")
{
enum rtx_code code = GET_CODE (op);
/* The V850E2V3 does not have a floating point NZ comparison operator.
Instead it is implemented as an EQ comparison and this function ensures
that the branch_nz_normal and set_nz_insn patterns are used to examine
(and invert) the result of the floating point comparison. */
if (GET_RTX_CLASS (code) != RTX_COMPARE
&& GET_RTX_CLASS (code) != RTX_COMM_COMPARE)
return 0;
if (mode != GET_MODE (op) && mode != VOIDmode)
return 0;
if ((GET_CODE (XEXP (op, 0)) != REG
|| REGNO (XEXP (op, 0)) != CC_REGNUM)
|| XEXP (op, 1) != const0_rtx)
return 0;
if (GET_MODE (XEXP (op, 0)) == CC_FPU_NEmode)
return code == NE;
return 0;
})

View File

@ -40,8 +40,6 @@ extern char * construct_restore_jr (rtx);
extern char * construct_dispose_instruction (rtx);
extern char * construct_prepare_instruction (rtx);
extern int ep_memory_operand (rtx, enum machine_mode, int);
extern int v850_float_z_comparison_operator (rtx, enum machine_mode);
extern int v850_float_nz_comparison_operator (rtx, enum machine_mode);
extern rtx v850_gen_compare (enum rtx_code, enum machine_mode,
rtx, rtx);
extern enum machine_mode v850_gen_float_compare (enum rtx_code,

View File

@ -898,61 +898,6 @@ output_move_single (rtx * operands)
return "";
}
/* Generate comparison code. */
int
v850_float_z_comparison_operator (rtx op, enum machine_mode mode)
{
enum rtx_code code = GET_CODE (op);
if (GET_RTX_CLASS (code) != RTX_COMPARE
&& GET_RTX_CLASS (code) != RTX_COMM_COMPARE)
return 0;
if (mode != GET_MODE (op) && mode != VOIDmode)
return 0;
if ((GET_CODE (XEXP (op, 0)) != REG
|| REGNO (XEXP (op, 0)) != CC_REGNUM)
|| XEXP (op, 1) != const0_rtx)
return 0;
if (GET_MODE (XEXP (op, 0)) == CC_FPU_LTmode)
return code == LT;
if (GET_MODE (XEXP (op, 0)) == CC_FPU_LEmode)
return code == LE;
if (GET_MODE (XEXP (op, 0)) == CC_FPU_EQmode)
return code == EQ;
return 0;
}
int
v850_float_nz_comparison_operator (rtx op, enum machine_mode mode)
{
enum rtx_code code = GET_CODE (op);
if (GET_RTX_CLASS (code) != RTX_COMPARE
&& GET_RTX_CLASS (code) != RTX_COMM_COMPARE)
return 0;
if (mode != GET_MODE (op) && mode != VOIDmode)
return 0;
if ((GET_CODE (XEXP (op, 0)) != REG
|| REGNO (XEXP (op, 0)) != CC_REGNUM)
|| XEXP (op, 1) != const0_rtx)
return 0;
if (GET_MODE (XEXP (op, 0)) == CC_FPU_GTmode)
return code == GT;
if (GET_MODE (XEXP (op, 0)) == CC_FPU_GEmode)
return code == GE;
if (GET_MODE (XEXP (op, 0)) == CC_FPU_NEmode)
return code == NE;
return code == GT || code == GE || code == NE;
}
enum machine_mode
v850_select_cc_mode (enum rtx_code cond, rtx op0, rtx op1 ATTRIBUTE_UNUSED)
{
@ -973,7 +918,7 @@ v850_select_cc_mode (enum rtx_code cond, rtx op0, rtx op1 ATTRIBUTE_UNUSED)
case NE:
return CC_FPU_NEmode;
default:
abort ();
gcc_unreachable ();
}
}
return CCmode;
@ -982,7 +927,7 @@ v850_select_cc_mode (enum rtx_code cond, rtx op0, rtx op1 ATTRIBUTE_UNUSED)
enum machine_mode
v850_gen_float_compare (enum rtx_code cond, enum machine_mode mode ATTRIBUTE_UNUSED, rtx op0, rtx op1)
{
if (GET_MODE(op0) == DFmode)
if (GET_MODE (op0) == DFmode)
{
switch (cond)
{
@ -998,17 +943,18 @@ v850_gen_float_compare (enum rtx_code cond, enum machine_mode mode ATTRIBUTE_UNU
case GT:
emit_insn (gen_cmpdf_gt_insn (op0, op1));
break;
case NE:
/* Note: There is no NE comparison operator. So we
perform an EQ comparison and invert the branch.
See v850_float_nz_comparison for how this is done. */
case EQ:
emit_insn (gen_cmpdf_eq_insn (op0, op1));
break;
case NE:
emit_insn (gen_cmpdf_ne_insn (op0, op1));
break;
default:
abort ();
gcc_unreachable ();
}
}
else if (GET_MODE(v850_compare_op0) == SFmode)
else if (GET_MODE (v850_compare_op0) == SFmode)
{
switch (cond)
{
@ -1024,20 +970,19 @@ v850_gen_float_compare (enum rtx_code cond, enum machine_mode mode ATTRIBUTE_UNU
case GT:
emit_insn (gen_cmpsf_gt_insn(op0, op1));
break;
case NE:
/* Note: There is no NE comparison operator. So we
perform an EQ comparison and invert the branch.
See v850_float_nz_comparison for how this is done. */
case EQ:
emit_insn (gen_cmpsf_eq_insn(op0, op1));
break;
case NE:
emit_insn (gen_cmpsf_ne_insn(op0, op1));
break;
default:
abort ();
gcc_unreachable ();
}
}
else
{
abort ();
}
gcc_unreachable ();
return v850_select_cc_mode (cond, op0, op1);
}

View File

@ -405,6 +405,114 @@
[(set_attr "length" "2,2")
(set_attr "cc" "compare")])
(define_expand "cbranchsf4"
[(set (pc)
(if_then_else (match_operator 0 "ordered_comparison_operator"
[(match_operand:SF 1 "register_operand")
(match_operand:SF 2 "register_operand")])
(label_ref (match_operand 3 ""))
(pc)))
(clobber (cc0))]
"TARGET_V850E2V3"
{
v850_compare_op0 = operands[1];
v850_compare_op1 = operands[2];
enum rtx_code cond = GET_CODE(operands[0]);
enum machine_mode mode;
rtx fcc_reg;
rtx cc_reg;
rtx tmp;
if (GET_MODE_CLASS (GET_MODE (v850_compare_op0)) != MODE_FLOAT)
FAIL;
mode = v850_gen_float_compare (cond, VOIDmode, v850_compare_op0, v850_compare_op1);
fcc_reg = gen_rtx_REG (mode, FCC_REGNUM);
cc_reg = gen_rtx_REG (mode, CC_REGNUM);
emit_insn(gen_rtx_SET (mode, cc_reg, fcc_reg));
tmp = gen_rtx_fmt_ee (cond, mode, cc_reg, const0_rtx);
tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
gen_rtx_LABEL_REF (VOIDmode, operands[3]), pc_rtx);
emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
DONE;
})
(define_insn "cstoresf4"
[(set (match_operand:SI 0 "register_operand" "=r")
(match_operator:SI 1 "ordered_comparison_operator"
[(match_operand:SF 2 "register_operand" "r")
(match_operand:SF 3 "register_operand" "r")]))]
"TARGET_V850E2V3"
{
if (GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE)
return "cmpf.s %c1, %z2, %z3 ; trfsr ; setf nz, %0";
if (GET_CODE (operands[1]) == LT || GET_CODE (operands[1]) == LE)
return "cmpf.s %c1, %z2, %z3 ; trfsr ; setf z, %0";
if (GET_CODE (operands[1]) == EQ)
return "cmpf.s eq, %z2, %z3 ; trfsr ; setf z, %0";
if (GET_CODE (operands[1]) == NE)
return "cmpf.s neq, %z2, %z3 ; trfsr ; setf nz, %0";
gcc_unreachable ();
}
[(set_attr "length" "12")
(set_attr "type" "fpu")]
)
(define_expand "cbranchdf4"
[(set (pc)
(if_then_else (match_operator 0 "ordered_comparison_operator"
[(match_operand:DF 1 "even_reg_operand")
(match_operand:DF 2 "even_reg_operand")])
(label_ref (match_operand 3 ""))
(pc)))
(clobber (cc0))]
"TARGET_V850E2V3"
{
v850_compare_op0 = operands[1];
v850_compare_op1 = operands[2];
enum rtx_code cond = GET_CODE(operands[0]);
enum machine_mode mode;
rtx fcc_reg;
rtx cc_reg;
rtx tmp;
if (GET_MODE_CLASS (GET_MODE (v850_compare_op0)) != MODE_FLOAT)
FAIL;
mode = v850_gen_float_compare (cond, VOIDmode, v850_compare_op0, v850_compare_op1);
fcc_reg = gen_rtx_REG (mode, FCC_REGNUM);
cc_reg = gen_rtx_REG (mode, CC_REGNUM);
emit_insn(gen_rtx_SET (mode, cc_reg, fcc_reg));
tmp = gen_rtx_fmt_ee (cond, mode, cc_reg, const0_rtx);
tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
gen_rtx_LABEL_REF (VOIDmode, operands[3]), pc_rtx);
emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
DONE;
})
(define_insn "cstoredf4"
[(set (match_operand:SI 0 "register_operand" "=r")
(match_operator:SI 1 "ordered_comparison_operator"
[(match_operand:DF 2 "even_reg_operand" "r")
(match_operand:DF 3 "even_reg_operand" "r")]))]
"TARGET_V850E2V3"
{
if (GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == GE)
return "cmpf.d %c1, %z2, %z3 ; trfsr ; setf nz, %0";
if (GET_CODE (operands[1]) == LT || GET_CODE (operands[1]) == LE)
return "cmpf.d %c1, %z2, %z3 ; trfsr ; setf z, %0";
if (GET_CODE (operands[1]) == EQ)
return "cmpf.d eq, %z2, %z3 ; trfsr ; setf z ,%0";
if (GET_CODE (operands[1]) == NE)
return "cmpf.d neq, %z2, %z3 ; trfsr ; setf nz, %0";
gcc_unreachable ();
}
[(set_attr "length" "12")
(set_attr "type" "fpu")]
)
(define_expand "cmpsf"
[(set (reg:CC CC_REGNUM)
(compare (match_operand:SF 0 "register_operand" "r")
@ -940,6 +1048,11 @@
(match_operand:SI 3 "reg_or_const_operand" "rI")))]
"(TARGET_V850E || TARGET_V850E2_ALL)"
{
/* Make sure that we have an integer comparison... */
if (GET_MODE (XEXP (operands[1], 0)) != CCmode
&& GET_MODE (XEXP (operands[1], 0)) != SImode)
FAIL;
if ((GET_CODE (operands[2]) == CONST_INT
&& GET_CODE (operands[3]) == CONST_INT))
{
@ -2210,7 +2323,7 @@
(compare:CC_FPU_LE (match_operand:SF 0 "register_operand" "r")
(match_operand:SF 1 "register_operand" "r")))]
"TARGET_USE_FPU"
"cmpf.s le,%z1,%z0"
"cmpf.s le, %z0, %z1"
[(set_attr "length" "4")
(set_attr "cc" "none_0hit")
(set_attr "type" "fpu")])
@ -2220,7 +2333,7 @@
(compare:CC_FPU_LT (match_operand:SF 0 "register_operand" "r")
(match_operand:SF 1 "register_operand" "r")))]
"TARGET_USE_FPU"
"cmpf.s lt,%z1,%z0"
"cmpf.s lt, %z0, %z1"
[(set_attr "length" "4")
(set_attr "cc" "none_0hit")
(set_attr "type" "fpu")])
@ -2230,7 +2343,7 @@
(compare:CC_FPU_GE (match_operand:SF 0 "register_operand" "r")
(match_operand:SF 1 "register_operand" "r")))]
"TARGET_USE_FPU"
"cmpf.s ge,%z1,%z0"
"cmpf.s le, %z1, %z0"
[(set_attr "length" "4")
(set_attr "cc" "none_0hit")
(set_attr "type" "fpu")])
@ -2240,7 +2353,7 @@
(compare:CC_FPU_GT (match_operand:SF 0 "register_operand" "r")
(match_operand:SF 1 "register_operand" "r")))]
"TARGET_USE_FPU"
"cmpf.s gt,%z1,%z0"
"cmpf.s lt, %z1, %z0"
[(set_attr "length" "4")
(set_attr "cc" "none_0hit")
(set_attr "type" "fpu")])
@ -2250,17 +2363,7 @@
(compare:CC_FPU_EQ (match_operand:SF 0 "register_operand" "r")
(match_operand:SF 1 "register_operand" "r")))]
"TARGET_USE_FPU"
"cmpf.s eq,%z1,%z0"
[(set_attr "length" "4")
(set_attr "cc" "none_0hit")
(set_attr "type" "fpu")])
(define_insn "cmpsf_ne_insn"
[(set (reg:CC_FPU_NE FCC_REGNUM)
(compare:CC_FPU_NE (match_operand:SF 0 "register_operand" "r")
(match_operand:SF 1 "register_operand" "r")))]
"TARGET_USE_FPU"
"cmpf.s neq,%z1,%z0"
"cmpf.s eq, %z0, %z1"
[(set_attr "length" "4")
(set_attr "cc" "none_0hit")
(set_attr "type" "fpu")])
@ -2272,7 +2375,7 @@
(compare:CC_FPU_LE (match_operand:DF 0 "even_reg_operand" "r")
(match_operand:DF 1 "even_reg_operand" "r")))]
"TARGET_USE_FPU"
"cmpf.d le,%z1,%z0"
"cmpf.d le, %z0, %z1"
[(set_attr "length" "4")
(set_attr "cc" "none_0hit")
(set_attr "type" "fpu")])
@ -2282,7 +2385,7 @@
(compare:CC_FPU_LT (match_operand:DF 0 "even_reg_operand" "r")
(match_operand:DF 1 "even_reg_operand" "r")))]
"TARGET_USE_FPU"
"cmpf.d lt,%z1,%z0"
"cmpf.d lt, %z0, %z1"
[(set_attr "length" "4")
(set_attr "cc" "none_0hit")
(set_attr "type" "fpu")])
@ -2292,7 +2395,7 @@
(compare:CC_FPU_GE (match_operand:DF 0 "even_reg_operand" "r")
(match_operand:DF 1 "even_reg_operand" "r")))]
"TARGET_USE_FPU"
"cmpf.d ge,%z1,%z0"
"cmpf.d le, %z1, %z0"
[(set_attr "length" "4")
(set_attr "cc" "none_0hit")
(set_attr "type" "fpu")])
@ -2300,9 +2403,9 @@
(define_insn "cmpdf_gt_insn"
[(set (reg:CC_FPU_GT FCC_REGNUM)
(compare:CC_FPU_GT (match_operand:DF 0 "even_reg_operand" "r")
(match_operand:DF 1 "even_reg_operand" "r")))]
(match_operand:DF 1 "even_reg_operand" "r")))]
"TARGET_USE_FPU"
"cmpf.d gt,%z1,%z0"
"cmpf.d lt, %z1, %z0"
[(set_attr "length" "4")
(set_attr "cc" "none_0hit")
(set_attr "type" "fpu")])
@ -2312,22 +2415,11 @@
(compare:CC_FPU_EQ (match_operand:DF 0 "even_reg_operand" "r")
(match_operand:DF 1 "even_reg_operand" "r")))]
"TARGET_USE_FPU"
"cmpf.d eq,%z1,%z0"
"cmpf.d eq, %z0, %z1"
[(set_attr "length" "4")
(set_attr "cc" "none_0hit")
(set_attr "type" "fpu")])
(define_insn "cmpdf_ne_insn"
[(set (reg:CC_FPU_NE FCC_REGNUM)
(compare:CC_FPU_NE (match_operand:DF 0 "even_reg_operand" "r")
(match_operand:DF 1 "even_reg_operand" "r")))]
"TARGET_USE_FPU"
"cmpf.d neq,%z1,%z0"
[(set_attr "length" "4")
(set_attr "cc" "none_0hit")
(set_attr "type" "fpu")])
;;
;; Transfer a v850e2v3 fcc to the Z bit of CC0 (this is necessary to do a
;; conditional branch based on a floating-point compare)