More multi-register structure return recognition fixes and:

* config/sparc/sparc.md (movdf_const_intreg_sp64): Disable.

From-SVN: r22396
This commit is contained in:
David S. Miller 1998-09-12 03:45:22 +00:00 committed by David S. Miller
parent 86465af734
commit c0222c217b
4 changed files with 129 additions and 22 deletions

View File

@ -6,6 +6,16 @@ Fri Sep 11 23:55:54 1998 David S. Miller <davem@pierdol.cobaltmicro.com>
(count_reg_sets_1): Likewise.
(count_reg_references): Likewise.
* rtlanal.c (note_stores): Likewise.
(reg_overlap_mentioned_p): Likewise.
* haifa-sched.c (check_live_1): Likewise.
(update_live_1): Likewise.
(sched_analyze_1): Likewise.
(sched_note_set): Likewise.
(birthing_insn_p): Likewise.
(attach_deaths): Likewise.
* config/sparc/sparc.md (movdf_const_intreg_sp64): Disable.
Fri Sep 11 22:57:55 1998 Eric Dumazet <dumazet@cosmosbay.com>

View File

@ -2949,10 +2949,15 @@
[(set_attr "type" "move")
(set_attr "length" "1")])
;; ?? This and split disabled on sparc64... When I change the destination
;; ?? reg to be DImode to emit the constant formation code, the instruction
;; ?? scheduler does not want to believe that it is the same as the DFmode
;; ?? subreg we started with... See the SFmode version of this above to
;; ?? see how it can be handled.
(define_insn "*movdf_const_intreg_sp64"
[(set (match_operand:DF 0 "general_operand" "=e,e,r")
(match_operand:DF 1 "" "m,o,F"))]
"TARGET_FPU && TARGET_ARCH64
"0 && TARGET_FPU && TARGET_ARCH64
&& GET_CODE (operands[1]) == CONST_DOUBLE
&& GET_CODE (operands[0]) == REG"
"*
@ -2968,7 +2973,8 @@
(define_split
[(set (match_operand:DF 0 "register_operand" "")
(match_operand:DF 1 "const_double_operand" ""))]
"TARGET_FPU
"! TARGET_ARCH64
&& TARGET_FPU
&& GET_CODE (operands[1]) == CONST_DOUBLE
&& (GET_CODE (operands[0]) == REG
&& REGNO (operands[0]) < 32)
@ -2985,22 +2991,39 @@
operands[0] = alter_subreg (operands[0]);
operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
GEN_INT (l[0])));
/* Slick... but this trick loses if this subreg constant part
can be done in one insn. */
if (l[1] == l[0]
&& !(SPARC_SETHI_P (l[0])
|| SPARC_SIMM13_P (l[0])))
if (TARGET_ARCH64)
{
emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
gen_highpart (SImode, operands[0])));
#if HOST_BITS_PER_WIDE_INT == 64
HOST_WIDE_INT val;
val = ((HOST_WIDE_INT)l[1] |
((HOST_WIDE_INT)l[0] << 32));
emit_insn (gen_movdi (operands[0], GEN_INT (val)));
#else
emit_insn (gen_movdi (operands[0],
gen_rtx_CONST_DOUBLE (VOIDmode, const0_rtx,
l[1], l[0])));
#endif
}
else
{
emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
GEN_INT (l[1])));
emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
GEN_INT (l[0])));
/* Slick... but this trick loses if this subreg constant part
can be done in one insn. */
if (l[1] == l[0]
&& !(SPARC_SETHI_P (l[0])
|| SPARC_SIMM13_P (l[0])))
{
emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
gen_highpart (SImode, operands[0])));
}
else
{
emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
GEN_INT (l[1])));
}
}
DONE;
}")

View File

@ -2117,6 +2117,16 @@ check_live_1 (src, x)
|| GET_CODE (reg) == STRICT_LOW_PART)
reg = XEXP (reg, 0);
if (GET_CODE (reg) == PARALLEL
&& GET_MODE (reg) == BLKmode)
{
register int i;
for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
if (check_live_1 (src, XVECEXP (reg, 0, i)))
return 1;
return 0;
}
if (GET_CODE (reg) != REG)
return 1;
@ -2185,6 +2195,15 @@ update_live_1 (src, x)
|| GET_CODE (reg) == STRICT_LOW_PART)
reg = XEXP (reg, 0);
if (GET_CODE (reg) == PARALLEL
&& GET_MODE (reg) == BLKmode)
{
register int i;
for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
update_live_1 (src, XVECEXP (reg, 0, i));
return;
}
if (GET_CODE (reg) != REG)
return;
@ -3288,6 +3307,17 @@ sched_analyze_1 (x, insn)
if (dest == 0)
return;
if (GET_CODE (dest) == PARALLEL
&& GET_MODE (dest) == BLKmode)
{
register int i;
for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
sched_analyze_1 (XVECEXP (dest, 0, i), insn);
if (GET_CODE (x) == SET)
sched_analyze_2 (SET_SRC (x), insn);
return;
}
while (GET_CODE (dest) == STRICT_LOW_PART || GET_CODE (dest) == SUBREG
|| GET_CODE (dest) == ZERO_EXTRACT || GET_CODE (dest) == SIGN_EXTRACT)
{
@ -3982,6 +4012,15 @@ sched_note_set (x, death)
if (reg == 0)
return;
if (GET_CODE (reg) == PARALLEL
&& GET_MODE (reg) == BLKmode)
{
register int i;
for (i = XVECLEN (reg, 0) - 1; i >= 0; i--)
sched_note_set (XVECEXP (reg, 0, i), death);
return;
}
while (GET_CODE (reg) == SUBREG || GET_CODE (reg) == STRICT_LOW_PART
|| GET_CODE (reg) == SIGN_EXTRACT || GET_CODE (reg) == ZERO_EXTRACT)
{
@ -4215,18 +4254,31 @@ birthing_insn_p (pat)
return 0;
if (GET_CODE (pat) == SET
&& GET_CODE (SET_DEST (pat)) == REG)
&& (GET_CODE (SET_DEST (pat)) == REG
|| (GET_CODE (SET_DEST (pat)) == PARALLEL
&& GET_MODE (SET_DEST (pat)) == BLKmode)))
{
rtx dest = SET_DEST (pat);
int i = REGNO (dest);
int i;
/* It would be more accurate to use refers_to_regno_p or
reg_mentioned_p to determine when the dest is not live before this
insn. */
if (REGNO_REG_SET_P (bb_live_regs, i))
return (REG_N_SETS (i) == 1);
reg_mentioned_p to determine when the dest is not live before this
insn. */
if (GET_CODE (dest) == REG)
{
i = REGNO (dest);
if (REGNO_REG_SET_P (bb_live_regs, i))
return (REG_N_SETS (i) == 1);
}
else
{
for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
{
int regno = REGNO (SET_DEST (XVECEXP (dest, 0, i)));
if (REGNO_REG_SET_P (bb_live_regs, regno))
return (REG_N_SETS (regno) == 1);
}
}
return 0;
}
if (GET_CODE (pat) == PARALLEL)
@ -4638,6 +4690,16 @@ attach_deaths (x, insn, set_p)
attach_deaths (XEXP (x, 2), insn, 0);
return;
case PARALLEL:
if (set_p
&& GET_MODE (x) == BLKmode)
{
for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
attach_deaths (SET_DEST (XVECEXP (x, 0, i)), insn, 1);
return;
}
/* fallthrough */
default:
/* Other cases: walk the insn. */
fmt = GET_RTX_FORMAT (code);

View File

@ -851,6 +851,18 @@ reg_overlap_mentioned_p (x, in)
else if (GET_CODE (x) == SCRATCH || GET_CODE (x) == PC
|| GET_CODE (x) == CC0)
return reg_mentioned_p (x, in);
else if (GET_CODE (x) == PARALLEL
&& GET_MODE (x) == BLKmode)
{
register int i;
/* If any register in here refers to it
we return true. */
for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
if (reg_overlap_mentioned_p (SET_DEST (XVECEXP (x, 0, i)), in))
return 1;
return 0;
}
else
abort ();