From: David S. Miller Date: Mon, 10 Aug 1998 23:47:28 +0000 (+0000) Subject: sparc.c (input_operand): Do not accept a LO_SUM MEM for TFmode when !v9. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=03ad6f4d34a4fc496c2bf886444a3a2862deddfa;p=gcc.git sparc.c (input_operand): Do not accept a LO_SUM MEM for TFmode when !v9. * config/sparc/sparc.c (input_operand): Do not accept a LO_SUM MEM for TFmode when !v9. We require offsettable memory addresses. * config/sparc/sparc.h (ALTER_HARD_SUBREG): Handle TFmode to DFmode register number conversions. * config/sparc/sparc.md (define_split DFmode moves): If register is a SUBREG do alter_subreg on it before using. (define_expand movtf): Fixup comment about alignment on v9. (define_split TFmode moves): Don't use gen_{high,low}part, create explicit SUBREGs instead. From-SVN: r21658 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7ce44f1e55d..ee408a4e697 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +Mon Aug 10 22:39:09 1998 David S. Miller + + * config/sparc/sparc.c (input_operand): Do not accept a LO_SUM MEM + for TFmode when !v9. We require offsettable memory addresses. + * config/sparc/sparc.h (ALTER_HARD_SUBREG): Handle TFmode to + DFmode register number conversions. + * config/sparc/sparc.md (define_split DFmode moves): If register + is a SUBREG do alter_subreg on it before using. + (define_expand movtf): Fixup comment about alignment on v9. + (define_split TFmode moves): Don't use gen_{high,low}part, create + explicit SUBREGs instead. + Mon Aug 10 19:02:55 1998 John Carr * Makefile.in (mbchar.o): Depend on mbchar.c. diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index c4411fae5fd..94e86fa3aa7 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -1010,8 +1010,17 @@ input_operand (op, mode) rtx inside = XEXP (op, 0); if (GET_CODE (inside) == LO_SUM) - return (register_operand (XEXP (inside, 0), Pmode) - && CONSTANT_P (XEXP (inside, 1))); + { + /* We can't allow these because all of the splits + (eventually as they trickle down into DFmode + splits) require offsettable memory references. */ + if (! TARGET_V9 + && GET_MODE (op) == TFmode) + return 0; + + return (register_operand (XEXP (inside, 0), Pmode) + && CONSTANT_P (XEXP (inside, 1))); + } return memory_address_p (mode, inside); } diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h index 9749bd1a3b6..110e987eadd 100644 --- a/gcc/config/sparc/sparc.h +++ b/gcc/config/sparc/sparc.h @@ -980,7 +980,8 @@ while (0) /* A subreg in 64 bit mode will have the wrong offset for a floating point register. The least significant part is at offset 1, compared to 0 for - integer registers. This only applies when FMODE is a larger mode. */ + integer registers. This only applies when FMODE is a larger mode. + We also need to handle a special case of TF-->DF conversions. */ #define ALTER_HARD_SUBREG(TMODE, WORD, FMODE, REGNO) \ (TARGET_ARCH64 \ && (REGNO) >= SPARC_FIRST_FP_REG \ @@ -988,7 +989,9 @@ while (0) && (TMODE) == SImode \ && !((FMODE) == QImode || (FMODE) == HImode) \ ? ((REGNO) + 1) \ - : ((REGNO) + (WORD))) + : ((TMODE) == DFmode && (FMODE) == TFmode) \ + ? ((REGNO) + ((WORD) * 2)) \ + : ((REGNO) + (WORD))) /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. See sparc.c for how we initialize this. */ diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index 5cf7e807db4..e054d25db66 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -2995,6 +2995,9 @@ self_reference = reg_mentioned_p (operands[0], XEXP (XEXP (word1, 0), 0)); + if (GET_CODE (operands[0]) == SUBREG) + operands[0] = alter_subreg (operands[0]); + if (self_reference != 0 && WORDS_BIG_ENDIAN) { @@ -3028,6 +3031,8 @@ rtx word1 = change_address (operands[0], SFmode, plus_constant_for_output (XEXP (word0, 0), 4)); + if (GET_CODE (operands[1]) == SUBREG) + operands[1] = alter_subreg (operands[1]); emit_insn (gen_movsf (word0, gen_highpart (SFmode, operands[1]))); emit_insn (gen_movsf (word1, @@ -3054,8 +3059,8 @@ operands[1])); } - /* Handle MEM cases first, note that even v9 only guarentees - 8-byte alignment for quads so... */ + /* Handle MEM cases first, note that only v9 guarentees + full 16-byte alignment for quads. */ if (GET_CODE (operands[0]) == MEM) { if (register_operand (operands[1], TFmode)) @@ -3179,10 +3184,11 @@ movtf_is_ok: if (GET_CODE (set_src) == SUBREG) set_src = alter_subreg (set_src); - dest1 = gen_highpart (DFmode, set_dest); - dest2 = gen_lowpart (DFmode, set_dest); - src1 = gen_highpart (DFmode, set_src); - src2 = gen_lowpart (DFmode, set_src); + /* Ugly, but gen_highpart will crap out here for 32-bit targets. */ + dest1 = gen_rtx_SUBREG (DFmode, set_dest, WORDS_BIG_ENDIAN == 0); + dest2 = gen_rtx_SUBREG (DFmode, set_dest, WORDS_BIG_ENDIAN != 0); + src1 = gen_rtx_SUBREG (DFmode, set_src, WORDS_BIG_ENDIAN == 0); + src2 = gen_rtx_SUBREG (DFmode, set_src, WORDS_BIG_ENDIAN != 0); /* Now emit using the real source and destination we found, swapping the order if we detect overlap. */ @@ -3210,11 +3216,13 @@ movtf_is_ok: rtx word0 = change_address (operands[1], DFmode, NULL_RTX); rtx word1 = change_address (operands[1], DFmode, plus_constant_for_output (XEXP (word0, 0), 8)); + rtx dest1, dest2; - emit_insn (gen_movdf (gen_highpart (DFmode, operands[0]), - word0)); - emit_insn (gen_movdf (gen_lowpart (DFmode, operands[0]), - word1)); + /* Ugly, but gen_highpart will crap out here for 32-bit targets. */ + dest1 = gen_rtx_SUBREG (DFmode, operands[0], WORDS_BIG_ENDIAN == 0); + dest2 = gen_rtx_SUBREG (DFmode, operands[0], WORDS_BIG_ENDIAN != 0); + emit_insn (gen_movdf (dest1, word0)); + emit_insn (gen_movdf (dest2, word1)); DONE; }") @@ -3229,11 +3237,13 @@ movtf_is_ok: rtx word0 = change_address (operands[0], DFmode, NULL_RTX); rtx word1 = change_address (operands[0], DFmode, plus_constant_for_output (XEXP (word0, 0), 8)); + rtx src1, src2; - emit_insn (gen_movdf (word0, - gen_highpart (DFmode, operands[1]))); - emit_insn (gen_movdf (word1, - gen_lowpart (DFmode, operands[1]))); + /* Ugly, but gen_highpart will crap out here for 32-bit targets. */ + src1 = gen_rtx_SUBREG (DFmode, operands[1], WORDS_BIG_ENDIAN == 0); + src2 = gen_rtx_SUBREG (DFmode, operands[1], WORDS_BIG_ENDIAN != 0); + emit_insn (gen_movdf (word0, src1)); + emit_insn (gen_movdf (word1, src2)); DONE; }")