aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid S. Miller <davem@pierdol.cobaltmicro.com>1998-08-10 23:47:28 +0000
committerDavid S. Miller <davem@gcc.gnu.org>1998-08-10 16:47:28 -0700
commit03ad6f4d34a4fc496c2bf886444a3a2862deddfa (patch)
treeb6211a7b274880a94bf3bdeb3f061847710d0acb
parentb8d80a3a83398892f4914c8948a3becd59c8c394 (diff)
downloadgcc-03ad6f4d34a4fc496c2bf886444a3a2862deddfa.zip
gcc-03ad6f4d34a4fc496c2bf886444a3a2862deddfa.tar.gz
gcc-03ad6f4d34a4fc496c2bf886444a3a2862deddfa.tar.bz2
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
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/config/sparc/sparc.c13
-rw-r--r--gcc/config/sparc/sparc.h7
-rw-r--r--gcc/config/sparc/sparc.md38
4 files changed, 52 insertions, 18 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7ce44f1..ee408a4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index c4411fa..94e86fa 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 9749bd1..110e987 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 5cf7e80..e054d25 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;
}")