From c0222c217b95e4c8f8cc34d4aecd0298a41ec5ea Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 12 Sep 1998 03:45:22 +0000 Subject: [PATCH] More multi-register structure return recognition fixes and: * config/sparc/sparc.md (movdf_const_intreg_sp64): Disable. From-SVN: r22396 --- gcc/ChangeLog | 10 +++++ gcc/config/sparc/sparc.md | 51 ++++++++++++++++++------- gcc/haifa-sched.c | 78 +++++++++++++++++++++++++++++++++++---- gcc/rtlanal.c | 12 ++++++ 4 files changed, 129 insertions(+), 22 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 63646a0f67a..98f60c72918 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -6,6 +6,16 @@ Fri Sep 11 23:55:54 1998 David S. Miller (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 diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index 781719c87ef..8129fa3dcfd 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -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; }") diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c index 10e25a13484..459987c279d 100644 --- a/gcc/haifa-sched.c +++ b/gcc/haifa-sched.c @@ -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); diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 41625ee2868..6e5fa77fd3e 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -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 (); -- 2.30.2