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
This commit is contained in:
David S. Miller 1998-08-10 23:47:28 +00:00 committed by David S. Miller
parent b8d80a3a83
commit 03ad6f4d34
4 changed files with 52 additions and 18 deletions

View File

@ -1,3 +1,15 @@
Mon Aug 10 22:39:09 1998 David S. Miller <davem@pierdol.cobaltmicro.com>
* 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 <jfc@mit.edu>
* Makefile.in (mbchar.o): Depend on mbchar.c.

View File

@ -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);
}

View File

@ -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. */

View File

@ -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;
}")