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:
parent
b8d80a3a83
commit
03ad6f4d34
4 changed files with 52 additions and 18 deletions
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
}")
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue