Commit 03ad6f4d by David S. Miller Committed by David S. Miller

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
parent b8d80a3a
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> Mon Aug 10 19:02:55 1998 John Carr <jfc@mit.edu>
* Makefile.in (mbchar.o): Depend on mbchar.c. * Makefile.in (mbchar.o): Depend on mbchar.c.
......
...@@ -1010,8 +1010,17 @@ input_operand (op, mode) ...@@ -1010,8 +1010,17 @@ input_operand (op, mode)
rtx inside = XEXP (op, 0); rtx inside = XEXP (op, 0);
if (GET_CODE (inside) == LO_SUM) 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); return memory_address_p (mode, inside);
} }
......
...@@ -980,7 +980,8 @@ while (0) ...@@ -980,7 +980,8 @@ while (0)
/* A subreg in 64 bit mode will have the wrong offset for a floating point /* 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 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) \ #define ALTER_HARD_SUBREG(TMODE, WORD, FMODE, REGNO) \
(TARGET_ARCH64 \ (TARGET_ARCH64 \
&& (REGNO) >= SPARC_FIRST_FP_REG \ && (REGNO) >= SPARC_FIRST_FP_REG \
...@@ -988,7 +989,9 @@ while (0) ...@@ -988,7 +989,9 @@ while (0)
&& (TMODE) == SImode \ && (TMODE) == SImode \
&& !((FMODE) == QImode || (FMODE) == HImode) \ && !((FMODE) == QImode || (FMODE) == HImode) \
? ((REGNO) + 1) \ ? ((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. /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
See sparc.c for how we initialize this. */ See sparc.c for how we initialize this. */
......
...@@ -2995,6 +2995,9 @@ ...@@ -2995,6 +2995,9 @@
self_reference = reg_mentioned_p (operands[0], self_reference = reg_mentioned_p (operands[0],
XEXP (XEXP (word1, 0), 0)); XEXP (XEXP (word1, 0), 0));
if (GET_CODE (operands[0]) == SUBREG)
operands[0] = alter_subreg (operands[0]);
if (self_reference != 0 if (self_reference != 0
&& WORDS_BIG_ENDIAN) && WORDS_BIG_ENDIAN)
{ {
...@@ -3028,6 +3031,8 @@ ...@@ -3028,6 +3031,8 @@
rtx word1 = change_address (operands[0], SFmode, rtx word1 = change_address (operands[0], SFmode,
plus_constant_for_output (XEXP (word0, 0), 4)); 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, emit_insn (gen_movsf (word0,
gen_highpart (SFmode, operands[1]))); gen_highpart (SFmode, operands[1])));
emit_insn (gen_movsf (word1, emit_insn (gen_movsf (word1,
...@@ -3054,8 +3059,8 @@ ...@@ -3054,8 +3059,8 @@
operands[1])); operands[1]));
} }
/* Handle MEM cases first, note that even v9 only guarentees /* Handle MEM cases first, note that only v9 guarentees
8-byte alignment for quads so... */ full 16-byte alignment for quads. */
if (GET_CODE (operands[0]) == MEM) if (GET_CODE (operands[0]) == MEM)
{ {
if (register_operand (operands[1], TFmode)) if (register_operand (operands[1], TFmode))
...@@ -3179,10 +3184,11 @@ movtf_is_ok: ...@@ -3179,10 +3184,11 @@ movtf_is_ok:
if (GET_CODE (set_src) == SUBREG) if (GET_CODE (set_src) == SUBREG)
set_src = alter_subreg (set_src); set_src = alter_subreg (set_src);
dest1 = gen_highpart (DFmode, set_dest); /* Ugly, but gen_highpart will crap out here for 32-bit targets. */
dest2 = gen_lowpart (DFmode, set_dest); dest1 = gen_rtx_SUBREG (DFmode, set_dest, WORDS_BIG_ENDIAN == 0);
src1 = gen_highpart (DFmode, set_src); dest2 = gen_rtx_SUBREG (DFmode, set_dest, WORDS_BIG_ENDIAN != 0);
src2 = gen_lowpart (DFmode, set_src); 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 /* Now emit using the real source and destination we found, swapping
the order if we detect overlap. */ the order if we detect overlap. */
...@@ -3210,11 +3216,13 @@ movtf_is_ok: ...@@ -3210,11 +3216,13 @@ movtf_is_ok:
rtx word0 = change_address (operands[1], DFmode, NULL_RTX); rtx word0 = change_address (operands[1], DFmode, NULL_RTX);
rtx word1 = change_address (operands[1], DFmode, rtx word1 = change_address (operands[1], DFmode,
plus_constant_for_output (XEXP (word0, 0), 8)); plus_constant_for_output (XEXP (word0, 0), 8));
rtx dest1, dest2;
emit_insn (gen_movdf (gen_highpart (DFmode, operands[0]), /* Ugly, but gen_highpart will crap out here for 32-bit targets. */
word0)); dest1 = gen_rtx_SUBREG (DFmode, operands[0], WORDS_BIG_ENDIAN == 0);
emit_insn (gen_movdf (gen_lowpart (DFmode, operands[0]), dest2 = gen_rtx_SUBREG (DFmode, operands[0], WORDS_BIG_ENDIAN != 0);
word1)); emit_insn (gen_movdf (dest1, word0));
emit_insn (gen_movdf (dest2, word1));
DONE; DONE;
}") }")
...@@ -3229,11 +3237,13 @@ movtf_is_ok: ...@@ -3229,11 +3237,13 @@ movtf_is_ok:
rtx word0 = change_address (operands[0], DFmode, NULL_RTX); rtx word0 = change_address (operands[0], DFmode, NULL_RTX);
rtx word1 = change_address (operands[0], DFmode, rtx word1 = change_address (operands[0], DFmode,
plus_constant_for_output (XEXP (word0, 0), 8)); plus_constant_for_output (XEXP (word0, 0), 8));
rtx src1, src2;
emit_insn (gen_movdf (word0, /* Ugly, but gen_highpart will crap out here for 32-bit targets. */
gen_highpart (DFmode, operands[1]))); src1 = gen_rtx_SUBREG (DFmode, operands[1], WORDS_BIG_ENDIAN == 0);
emit_insn (gen_movdf (word1, src2 = gen_rtx_SUBREG (DFmode, operands[1], WORDS_BIG_ENDIAN != 0);
gen_lowpart (DFmode, operands[1]))); emit_insn (gen_movdf (word0, src1));
emit_insn (gen_movdf (word1, src2));
DONE; DONE;
}") }")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment