aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDavid S. Miller <davem@pierdol.cobaltmicro.com>1998-09-12 03:45:22 +0000
committerDavid S. Miller <davem@gcc.gnu.org>1998-09-11 20:45:22 -0700
commitc0222c217b95e4c8f8cc34d4aecd0298a41ec5ea (patch)
tree126a9b30c0a9ea97ed7ecfeae273a0a869ec597e /gcc
parent86465af7347851ef4d3473eabb4c7088b5443e6d (diff)
downloadgcc-c0222c217b95e4c8f8cc34d4aecd0298a41ec5ea.zip
gcc-c0222c217b95e4c8f8cc34d4aecd0298a41ec5ea.tar.gz
gcc-c0222c217b95e4c8f8cc34d4aecd0298a41ec5ea.tar.bz2
More multi-register structure return recognition fixes and:
* config/sparc/sparc.md (movdf_const_intreg_sp64): Disable. From-SVN: r22396
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/config/sparc/sparc.md51
-rw-r--r--gcc/haifa-sched.c78
-rw-r--r--gcc/rtlanal.c12
4 files changed, 129 insertions, 22 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 63646a0..98f60c7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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>
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index 781719c..8129fa3 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 10e25a1..459987c 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 41625ee..6e5fa77 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 ();