aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJ"orn Rennecke <joern.rennecke@superh.com>2002-07-23 20:06:46 +0000
committerJoern Rennecke <amylaar@gcc.gnu.org>2002-07-23 21:06:46 +0100
commit451f86fdbce4602102d1786f13fafa278bbaa6c9 (patch)
treea4657d0936e95c87f5855af3090630b9fee49cb9 /gcc
parent1d5fa6b42508d546fe875bb6809e645523f01e70 (diff)
downloadgcc-451f86fdbce4602102d1786f13fafa278bbaa6c9.zip
gcc-451f86fdbce4602102d1786f13fafa278bbaa6c9.tar.gz
gcc-451f86fdbce4602102d1786f13fafa278bbaa6c9.tar.bz2
reload.c (find_reloads_toplev): Use simplify_gen_subreg.
gcc: * reload.c (find_reloads_toplev): Use simplify_gen_subreg. * simplify-rtx.c (simplify_subreg): When converting to a non-int mode, try to convert to an integer mode of matching size first. gcc/testsuite: * gcc.c-torture/compile/simd-4.c: New test. From-SVN: r55687
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/reload.c43
-rw-r--r--gcc/simplify-rtx.c19
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/simd-4.c15
5 files changed, 44 insertions, 43 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 36d45ca..95b81eb 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,4 +1,8 @@
-Tue Jul 23 20:56:03 2002 J"orn Rennecke <joern.rennecke@superh.com>
+Tue Jul 23 21:02:16 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * reload.c (find_reloads_toplev): Use simplify_gen_subreg.
+ * simplify-rtx.c (simplify_subreg): When converting to a non-int
+ mode, try to convert to an integer mode of matching size first.
* simplify-rtx.x (simplify_subreg): When constructing a CONST_VECTOR
from individual subregs, check that each subreg has been generated
diff --git a/gcc/reload.c b/gcc/reload.c
index 72e1674..7f3568c 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -4404,51 +4404,16 @@ find_reloads_toplev (x, opnum, type, ind_levels, is_set_dest, insn,
if (GET_MODE_BITSIZE (GET_MODE (x)) == BITS_PER_WORD
&& regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
- && reg_equiv_constant[regno] != 0
- && (tem = operand_subword (reg_equiv_constant[regno],
- SUBREG_BYTE (x) / UNITS_PER_WORD, 0,
- GET_MODE (SUBREG_REG (x)))) != 0)
+ && reg_equiv_constant[regno] != 0)
{
- /* TEM is now a word sized constant for the bits from X that
- we wanted. However, TEM may be the wrong representation.
-
- Use gen_lowpart_common to convert a CONST_INT into a
- CONST_DOUBLE and vice versa as needed according to by the mode
- of the SUBREG. */
- tem = gen_lowpart_common (GET_MODE (x), tem);
+ tem =
+ simplify_gen_subreg (GET_MODE (x), reg_equiv_constant[regno],
+ GET_MODE (SUBREG_REG (x)), SUBREG_BYTE (x));
if (!tem)
abort ();
return tem;
}
- /* If the SUBREG is wider than a word, the above test will fail.
- For example, we might have a SImode SUBREG of a DImode SUBREG_REG
- for a 16 bit target, or a DImode SUBREG of a TImode SUBREG_REG for
- a 32 bit target. We still can - and have to - handle this
- for non-paradoxical subregs of CONST_INTs. */
- if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
- && reg_equiv_constant[regno] != 0
- && GET_CODE (reg_equiv_constant[regno]) == CONST_INT
- && (GET_MODE_SIZE (GET_MODE (x))
- < GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))))
- {
- int shift = SUBREG_BYTE (x) * BITS_PER_UNIT;
- if (WORDS_BIG_ENDIAN)
- shift = (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (x)))
- - GET_MODE_BITSIZE (GET_MODE (x))
- - shift);
- /* Here we use the knowledge that CONST_INTs have a
- HOST_WIDE_INT field. */
- if (shift >= HOST_BITS_PER_WIDE_INT)
- shift = HOST_BITS_PER_WIDE_INT - 1;
- return GEN_INT (INTVAL (reg_equiv_constant[regno]) >> shift);
- }
-
- if (regno >= FIRST_PSEUDO_REGISTER && reg_renumber[regno] < 0
- && reg_equiv_constant[regno] != 0
- && GET_MODE (reg_equiv_constant[regno]) == VOIDmode)
- abort ();
-
/* If the subreg contains a reg that will be converted to a mem,
convert the subreg to a narrower memref now.
Otherwise, we would get (subreg (mem ...) ...),
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index d07de68..1791f2e 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -2347,8 +2347,7 @@ simplify_subreg (outermode, op, innermode, byte)
return NULL_RTX;
return simplify_subreg (outermode, op, new_mode, subbyte);
}
- else if (GET_MODE_CLASS (outermode) != MODE_VECTOR_INT
- && GET_MODE_CLASS (outermode) != MODE_VECTOR_FLOAT)
+ else if (GET_MODE_CLASS (outermode) == MODE_INT)
/* This shouldn't happen, but let's not do anything stupid. */
return NULL_RTX;
}
@@ -2387,7 +2386,8 @@ simplify_subreg (outermode, op, innermode, byte)
Later it we should move all simplification code here and rewrite
GEN_LOWPART_IF_POSSIBLE, GEN_HIGHPART, OPERAND_SUBWORD and friends
using SIMPLIFY_SUBREG. */
- if (subreg_lowpart_offset (outermode, innermode) == byte)
+ if (subreg_lowpart_offset (outermode, innermode) == byte
+ && GET_CODE (op) != CONST_VECTOR)
{
rtx new = gen_lowpart_if_possible (outermode, op);
if (new)
@@ -2406,6 +2406,19 @@ simplify_subreg (outermode, op, innermode, byte)
return new;
}
+ if (GET_MODE_CLASS (outermode) != MODE_INT)
+ {
+ enum machine_mode new_mode = int_mode_for_mode (outermode);
+
+ if (new_mode != innermode || byte != 0)
+ {
+ op = simplify_subreg (new_mode, op, innermode, byte);
+ if (! op)
+ return NULL_RTX;
+ return simplify_subreg (outermode, op, new_mode, 0);
+ }
+ }
+
offset = byte * BITS_PER_UNIT;
switch (GET_CODE (op))
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 41b879c..2d5649d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+Tue Jul 23 21:02:43 2002 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * gcc.c-torture/compile/simd-4.c: New test.
+
2002-07-22 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
PR c++/7347, c++/7348
diff --git a/gcc/testsuite/gcc.c-torture/compile/simd-4.c b/gcc/testsuite/gcc.c-torture/compile/simd-4.c
new file mode 100644
index 0000000..6ede943
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/simd-4.c
@@ -0,0 +1,15 @@
+typedef float floatvect2 __attribute__((mode(V4SF)));
+
+typedef union
+{
+ floatvect2 vector;
+ float f[2];
+}resfloatvect2;
+
+void tempf(floatvect2 *x, floatvect2 *y)
+{
+ floatvect2 temp= *x;
+ floatvect2 temp1=*y;
+ resfloatvect2 temp2;
+ *x=temp+temp1;
+}