aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDoug Evans <dje@gnu.org>1997-07-22 23:41:48 +0000
committerDoug Evans <dje@gnu.org>1997-07-22 23:41:48 +0000
commit31bc9eba585e7b705173fe4d7dfa552a452a0669 (patch)
tree5438ea25a416d81f99f3088f177c31969f9eeb29 /gcc
parent7671d67b18474ccaf6e8422bf48f6fa67694bbc4 (diff)
downloadgcc-31bc9eba585e7b705173fe4d7dfa552a452a0669.zip
gcc-31bc9eba585e7b705173fe4d7dfa552a452a0669.tar.gz
gcc-31bc9eba585e7b705173fe4d7dfa552a452a0669.tar.bz2
* sparc/sparc.c (gen_v9_scc): Handle early clobber of result.
From-SVN: r14519
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/sparc/sparc.c56
1 files changed, 27 insertions, 29 deletions
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 5d38528..ead4da0 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -967,11 +967,11 @@ gen_compare_reg (code, x, y)
This function is needed to turn
(set (reg:SI 110)
- (gt (reg:CCX 0 %g0)
+ (gt (reg:CCX 100 %icc)
(const_int 0)))
into
(set (reg:SI 110)
- (gt:DI (reg:CCX 0 %g0)
+ (gt:DI (reg:CCX 100 %icc)
(const_int 0)))
IE: The instruction recognizer needs to see the mode of the comparison to
@@ -979,65 +979,64 @@ gen_compare_reg (code, x, y)
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
- 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?
-*/
+ sparc_compare_op1. */
int
gen_v9_scc (compare_code, operands)
enum rtx_code compare_code;
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
&& (GET_MODE (sparc_compare_op0) == DImode
|| GET_MODE (operands[0]) == DImode))
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. */
if (TARGET_ARCH64
- && GET_MODE_CLASS (GET_MODE (sparc_compare_op0)) == MODE_INT
- && sparc_compare_op1 == const0_rtx
+ && GET_MODE_CLASS (GET_MODE (op0)) == MODE_INT
+ && op1 == const0_rtx
&& v9_regcmp_p (compare_code))
{
/* 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,
- but the combiner will remove the first insn. */
+ operands[0] == sparc_compare_op0. We don't assume they are equal
+ now though. */
if (compare_code == NE
&& 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],
gen_rtx (IF_THEN_ELSE, DImode,
gen_rtx (compare_code, DImode,
- sparc_compare_op0, const0_rtx),
+ op0, const0_rtx),
const1_rtx,
operands[0])));
return 1;
}
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);
- convert_move (temp, sparc_compare_op0, 0);
+ convert_move (temp, op0, 0);
}
else
- {
- temp = sparc_compare_op0;
- }
+ temp = op0;
emit_insn (gen_rtx (SET, VOIDmode, operands[0],
gen_rtx (IF_THEN_ELSE, GET_MODE (operands[0]),
gen_rtx (compare_code, DImode,
@@ -1048,8 +1047,7 @@ gen_v9_scc (compare_code, operands)
}
else
{
- operands[1] = gen_compare_reg (compare_code,
- sparc_compare_op0, sparc_compare_op1);
+ operands[1] = gen_compare_reg (compare_code, op0, op1);
switch (GET_MODE (operands[1]))
{