Commit 31bc9eba by Doug Evans

* sparc/sparc.c (gen_v9_scc): Handle early clobber of result.

From-SVN: r14519
parent 7671d67b
...@@ -967,11 +967,11 @@ gen_compare_reg (code, x, y) ...@@ -967,11 +967,11 @@ gen_compare_reg (code, x, y)
This function is needed to turn This function is needed to turn
(set (reg:SI 110) (set (reg:SI 110)
(gt (reg:CCX 0 %g0) (gt (reg:CCX 100 %icc)
(const_int 0))) (const_int 0)))
into into
(set (reg:SI 110) (set (reg:SI 110)
(gt:DI (reg:CCX 0 %g0) (gt:DI (reg:CCX 100 %icc)
(const_int 0))) (const_int 0)))
IE: The instruction recognizer needs to see the mode of the comparison to IE: The instruction recognizer needs to see the mode of the comparison to
...@@ -979,65 +979,64 @@ gen_compare_reg (code, x, y) ...@@ -979,65 +979,64 @@ gen_compare_reg (code, x, y)
define_expand, but leaving it out allows us to handle DI, SI, etc. define_expand, but leaving it out allows us to handle DI, SI, etc.
We refer to the global sparc compare operands sparc_compare_op0 and We refer to the global sparc compare operands sparc_compare_op0 and
sparc_compare_op1. sparc_compare_op1. */
??? Some of this is outdated as the scc insns set the mode of the
comparison now.
??? We optimize for the case where op1 is 0 and the comparison allows us to
use the "movrCC" insns. This reduces the generated code from three to two
insns. This way seems too brute force though. Is there a more elegant way
to achieve the same effect?
*/
int int
gen_v9_scc (compare_code, operands) gen_v9_scc (compare_code, operands)
enum rtx_code compare_code; enum rtx_code compare_code;
register rtx *operands; register rtx *operands;
{ {
rtx temp; rtx temp, op0, op1;
/* It might be that we'll never be called if this is true,
but keep this here for documentation at least. */
if (! TARGET_ARCH64 if (! TARGET_ARCH64
&& (GET_MODE (sparc_compare_op0) == DImode && (GET_MODE (sparc_compare_op0) == DImode
|| GET_MODE (operands[0]) == DImode)) || GET_MODE (operands[0]) == DImode))
return 0; return 0;
/* Handle the case where operands[0] == sparc_compare_op0.
We "early clobber" the result. */
if (REGNO (operands[0]) == REGNO (sparc_compare_op0))
{
op0 = gen_reg_rtx (GET_MODE (sparc_compare_op0));
emit_move_insn (op0, sparc_compare_op0);
}
else
op0 = sparc_compare_op0;
/* For consistency in the following. */
op1 = sparc_compare_op1;
/* Try to use the movrCC insns. */ /* Try to use the movrCC insns. */
if (TARGET_ARCH64 if (TARGET_ARCH64
&& GET_MODE_CLASS (GET_MODE (sparc_compare_op0)) == MODE_INT && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
&& sparc_compare_op1 == const0_rtx && op1 == const0_rtx
&& v9_regcmp_p (compare_code)) && v9_regcmp_p (compare_code))
{ {
/* Special case for op0 != 0. This can be done with one instruction if /* Special case for op0 != 0. This can be done with one instruction if
op0 can be clobbered. We store to a temp, and then clobber the temp, operands[0] == sparc_compare_op0. We don't assume they are equal
but the combiner will remove the first insn. */ now though. */
if (compare_code == NE if (compare_code == NE
&& GET_MODE (operands[0]) == DImode && GET_MODE (operands[0]) == DImode
&& GET_MODE (sparc_compare_op0) == DImode) && GET_MODE (op0) == DImode)
{ {
emit_insn (gen_rtx (SET, VOIDmode, operands[0], sparc_compare_op0)); emit_insn (gen_rtx (SET, VOIDmode, operands[0], op0));
emit_insn (gen_rtx (SET, VOIDmode, operands[0], emit_insn (gen_rtx (SET, VOIDmode, operands[0],
gen_rtx (IF_THEN_ELSE, DImode, gen_rtx (IF_THEN_ELSE, DImode,
gen_rtx (compare_code, DImode, gen_rtx (compare_code, DImode,
sparc_compare_op0, const0_rtx), op0, const0_rtx),
const1_rtx, const1_rtx,
operands[0]))); operands[0])));
return 1; return 1;
} }
emit_insn (gen_rtx (SET, VOIDmode, operands[0], const0_rtx)); emit_insn (gen_rtx (SET, VOIDmode, operands[0], const0_rtx));
if (GET_MODE (sparc_compare_op0) != DImode) if (GET_MODE (op0) != DImode)
{ {
temp = gen_reg_rtx (DImode); temp = gen_reg_rtx (DImode);
convert_move (temp, sparc_compare_op0, 0); convert_move (temp, op0, 0);
} }
else else
{ temp = op0;
temp = sparc_compare_op0;
}
emit_insn (gen_rtx (SET, VOIDmode, operands[0], emit_insn (gen_rtx (SET, VOIDmode, operands[0],
gen_rtx (IF_THEN_ELSE, GET_MODE (operands[0]), gen_rtx (IF_THEN_ELSE, GET_MODE (operands[0]),
gen_rtx (compare_code, DImode, gen_rtx (compare_code, DImode,
...@@ -1048,8 +1047,7 @@ gen_v9_scc (compare_code, operands) ...@@ -1048,8 +1047,7 @@ gen_v9_scc (compare_code, operands)
} }
else else
{ {
operands[1] = gen_compare_reg (compare_code, operands[1] = gen_compare_reg (compare_code, op0, op1);
sparc_compare_op0, sparc_compare_op1);
switch (GET_MODE (operands[1])) switch (GET_MODE (operands[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