aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2001-06-04 16:52:14 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2001-06-04 14:52:14 +0000
commite0e08ac26c828bca4b9323d3139eba9293f3ecf4 (patch)
treed351d9b0c5c56ead3c8dc57fbda5329e9a5df46f
parent95307c8e0167e5460471eecb7056913b63d6043a (diff)
downloadgcc-e0e08ac26c828bca4b9323d3139eba9293f3ecf4.zip
gcc-e0e08ac26c828bca4b9323d3139eba9293f3ecf4.tar.gz
gcc-e0e08ac26c828bca4b9323d3139eba9293f3ecf4.tar.bz2
simplify_rtx.c (simplify_subreg): Keep subregs on return values...
* simplify_rtx.c (simplify_subreg): Keep subregs on return values, check CLASS_CANNOT_CHANGE_MODE before avoiding subreg on hard reg, in case register wasn't OK previously, accept it now; allow subregs of frame pointer if reload completed and frame pointer is not needed. * combine.c (sombine_simplify_rtx): Fix comment; use subreg_lowpart_offset instead of subreg_lowpart_p (gen_lowpart_for_combine): Use subreg_lowpart_offset. * rtl.h (subreg_lowpart_parts_p): Kill. (subreg_lowpart_offset, subreg_highpart_offset): Declare. * simplify-rtx.c (simplify_subreg): Use subreg_lowpart_offset. * emit-rtl.c (gen_lowpart_SUBREG): Use subreg_lowpart_offset; (gen_lowpart_common): Likewise. (subreg_lowpart_p): Likewise. (subreg_lowpart_parts_p): Kill. (subreg_lowpart_offset, subreg_highpart_offset): New function. * emit-rtl.c (gen_lowpart_common): Use simplify_gen_subreg to simplify SUBREG and REG. (gen_highpart): Use simplify_gen_subreg for all simplifications. * emit-rtl.c (gen_realpart, gen_imagpart): Do not handle CONCAT specially. * rtlanal.c (replace_regs): Use simplify_gen_subreg From-SVN: r42850
-rw-r--r--gcc/ChangeLog29
-rw-r--r--gcc/combine.c21
-rw-r--r--gcc/emit-rtl.c209
-rw-r--r--gcc/rtl.h7
-rw-r--r--gcc/rtlanal.c37
-rw-r--r--gcc/simplify-rtx.c24
6 files changed, 107 insertions, 220 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b688945..d387b24 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,32 @@
+Mon Jun 4 16:50:33 CEST 2001 Jan Hubicka <jh@suse.cz>
+
+ * simplify_rtx.c (simplify_subreg): Keep subregs on return values,
+ check CLASS_CANNOT_CHANGE_MODE before avoiding subreg on hard reg,
+ in case register wasn't OK previously, accept it now; allow
+ subregs of frame pointer if reload completed and frame pointer
+ is not needed.
+
+ * combine.c (sombine_simplify_rtx): Fix comment;
+ use subreg_lowpart_offset instead of subreg_lowpart_p
+ (gen_lowpart_for_combine): Use subreg_lowpart_offset.
+ * rtl.h (subreg_lowpart_parts_p): Kill.
+ (subreg_lowpart_offset, subreg_highpart_offset): Declare.
+ * simplify-rtx.c (simplify_subreg): Use subreg_lowpart_offset.
+ * emit-rtl.c (gen_lowpart_SUBREG): Use subreg_lowpart_offset;
+ (gen_lowpart_common): Likewise.
+ (subreg_lowpart_p): Likewise.
+ (subreg_lowpart_parts_p): Kill.
+ (subreg_lowpart_offset, subreg_highpart_offset): New function.
+
+ * emit-rtl.c (gen_lowpart_common): Use simplify_gen_subreg
+ to simplify SUBREG and REG.
+ (gen_highpart): Use simplify_gen_subreg for all simplifications.
+
+ * emit-rtl.c (gen_realpart, gen_imagpart): Do not handle
+ CONCAT specially.
+
+ * rtlanal.c (replace_regs): Use simplify_gen_subreg
+
Mon Jun 4 09:21:19 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* tree.def (ARRAY_RANGE_REF): New code.
diff --git a/gcc/combine.c b/gcc/combine.c
index bfa97b0..e34ab2f 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -3715,7 +3715,7 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
/* If CODE is an associative operation not otherwise handled, see if we
can associate some operands. This can win if they are constants or
- if they are logically related (i.e. (a & b) & a. */
+ if they are logically related (i.e. (a & b) & a). */
if ((code == PLUS || code == MINUS
|| code == MULT || code == AND || code == IOR || code == XOR
|| code == DIV || code == UDIV
@@ -3774,7 +3774,7 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
/* simplify_subreg can't use gen_lowpart_for_combine. */
if (CONSTANT_P (SUBREG_REG (x))
- && subreg_lowpart_parts_p (mode, op0_mode, SUBREG_BYTE (x)))
+ && subreg_lowpart_offset (mode, op0_mode) == SUBREG_BYTE (x))
return gen_lowpart_for_combine (mode, SUBREG_REG (x));
{
@@ -9765,18 +9765,13 @@ gen_lowpart_for_combine (mode, x)
else
{
int offset = 0;
+ rtx res;
- if ((WORDS_BIG_ENDIAN || BYTES_BIG_ENDIAN)
- && GET_MODE_SIZE (GET_MODE (x)) > GET_MODE_SIZE (mode))
- {
- int difference = (GET_MODE_SIZE (GET_MODE (x))
- - GET_MODE_SIZE (mode));
- if (WORDS_BIG_ENDIAN)
- offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
- if (BYTES_BIG_ENDIAN)
- offset += difference % UNITS_PER_WORD;
- }
- return gen_rtx_SUBREG (mode, x, offset);
+ offset = subreg_lowpart_offset (mode, GET_MODE (x));
+ res = simplify_gen_subreg (mode, x, GET_MODE (x), offset);
+ if (res)
+ return res;
+ return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
}
}
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 7a98f20..6c72a99 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -381,22 +381,12 @@ gen_lowpart_SUBREG (mode, reg)
rtx reg;
{
enum machine_mode inmode;
- int offset;
inmode = GET_MODE (reg);
if (inmode == VOIDmode)
inmode = mode;
- offset = 0;
- if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (inmode)
- && (WORDS_BIG_ENDIAN || BYTES_BIG_ENDIAN))
- {
- offset = GET_MODE_SIZE (inmode) - GET_MODE_SIZE (mode);
- if (! BYTES_BIG_ENDIAN)
- offset = (offset / UNITS_PER_WORD) * UNITS_PER_WORD;
- else if (! WORDS_BIG_ENDIAN)
- offset %= UNITS_PER_WORD;
- }
- return gen_rtx_SUBREG (mode, reg, offset);
+ return gen_rtx_SUBREG (mode, reg,
+ subreg_lowpart_offset (mode, inmode));
}
/* rtx gen_rtx (code, mode, [element1, ..., elementn])
@@ -761,16 +751,7 @@ gen_lowpart_common (mode, x)
> ((xsize + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)))
return 0;
- if ((WORDS_BIG_ENDIAN || BYTES_BIG_ENDIAN)
- && xsize > msize)
- {
- int difference = xsize - msize;
-
- if (WORDS_BIG_ENDIAN)
- offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
- if (BYTES_BIG_ENDIAN)
- offset += difference % UNITS_PER_WORD;
- }
+ offset = subreg_lowpart_offset (mode, GET_MODE (x));
if ((GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND)
&& (GET_MODE_CLASS (mode) == MODE_INT
@@ -791,61 +772,8 @@ gen_lowpart_common (mode, x)
else if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (x)))
return gen_rtx_fmt_e (GET_CODE (x), mode, XEXP (x, 0));
}
- else if (GET_CODE (x) == SUBREG
- && (GET_MODE_SIZE (mode) <= UNITS_PER_WORD
- || GET_MODE_SIZE (mode) == GET_MODE_UNIT_SIZE (GET_MODE (x))))
- {
- int final_offset;
-
- if (GET_MODE (SUBREG_REG (x)) == mode && subreg_lowpart_p (x))
- return SUBREG_REG (x);
-
- /* When working with SUBREGs the rule is that the byte
- offset must be a multiple of the SUBREG's mode. */
- final_offset = SUBREG_BYTE (x) + offset;
- final_offset = (final_offset / GET_MODE_SIZE (mode));
- final_offset = (final_offset * GET_MODE_SIZE (mode));
- return gen_rtx_SUBREG (mode, SUBREG_REG (x), final_offset);
- }
- else if (GET_CODE (x) == REG)
- {
- /* Hard registers are done specially in certain cases. */
- if (REGNO (x) < FIRST_PSEUDO_REGISTER)
- {
- int final_regno = REGNO (x) +
- subreg_regno_offset (REGNO (x), GET_MODE (x),
- offset, mode);
-
- /* If the final regno is not valid for MODE, punt. */
- /* ??? We do allow it if the current REG is not valid for
- ??? it's mode. It is a kludge to work around how float/complex
- ??? arguments are passed on 32-bit Sparc and should be fixed. */
- if (! HARD_REGNO_MODE_OK (final_regno, mode)
- && HARD_REGNO_MODE_OK (REGNO (x), GET_MODE (x)))
- return 0;
-
- /* integrate.c can't handle parts of a return value register. */
- if ((! REG_FUNCTION_VALUE_P (x)
- || ! rtx_equal_function_value_matters)
-#ifdef CLASS_CANNOT_CHANGE_MODE
- && ! (CLASS_CANNOT_CHANGE_MODE_P (mode, GET_MODE (x))
- && GET_MODE_CLASS (GET_MODE (x)) != MODE_COMPLEX_INT
- && GET_MODE_CLASS (GET_MODE (x)) != MODE_COMPLEX_FLOAT
- && (TEST_HARD_REG_BIT
- (reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
- REGNO (x))))
-#endif
- /* We want to keep the stack, frame, and arg pointers
- special. */
- && x != frame_pointer_rtx
-#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
- && x != arg_pointer_rtx
-#endif
- && x != stack_pointer_rtx)
- return gen_rtx_REG (mode, final_regno);
- }
- return gen_rtx_SUBREG (mode, x, offset);
- }
+ else if (GET_CODE (x) == SUBREG || GET_CODE (x) == REG || GET_CODE (x) == CONCAT)
+ return simplify_gen_subreg (mode, x, GET_MODE (x), offset);
/* If X is a CONST_INT or a CONST_DOUBLE, extract the appropriate bits
from the low-order part of the constant. */
else if ((GET_MODE_CLASS (mode) == MODE_INT
@@ -1088,12 +1016,10 @@ gen_realpart (mode, x)
enum machine_mode mode;
register rtx x;
{
- if (GET_CODE (x) == CONCAT && GET_MODE (XEXP (x, 0)) == mode)
- return XEXP (x, 0);
- else if (WORDS_BIG_ENDIAN
- && GET_MODE_BITSIZE (mode) < BITS_PER_WORD
- && REG_P (x)
- && REGNO (x) < FIRST_PSEUDO_REGISTER)
+ if (WORDS_BIG_ENDIAN
+ && GET_MODE_BITSIZE (mode) < BITS_PER_WORD
+ && REG_P (x)
+ && REGNO (x) < FIRST_PSEUDO_REGISTER)
internal_error
("Can't access real part of complex value in hard register");
else if (WORDS_BIG_ENDIAN)
@@ -1110,9 +1036,7 @@ gen_imagpart (mode, x)
enum machine_mode mode;
register rtx x;
{
- if (GET_CODE (x) == CONCAT && GET_MODE (XEXP (x, 0)) == mode)
- return XEXP (x, 1);
- else if (WORDS_BIG_ENDIAN)
+ if (WORDS_BIG_ENDIAN)
return gen_lowpart (mode, x);
else if (! WORDS_BIG_ENDIAN
&& GET_MODE_BITSIZE (mode) < BITS_PER_WORD
@@ -1195,109 +1119,62 @@ gen_highpart (mode, x)
register rtx x;
{
unsigned int msize = GET_MODE_SIZE (mode);
- unsigned int xsize = GET_MODE_SIZE (GET_MODE (x));
+ rtx result;
/* This case loses if X is a subreg. To catch bugs early,
complain if an invalid MODE is used even in other cases. */
if (msize > UNITS_PER_WORD
&& msize != GET_MODE_UNIT_SIZE (GET_MODE (x)))
abort ();
- if (GET_CODE (x) == CONST_DOUBLE
-#if !(TARGET_FLOAT_FORMAT != HOST_FLOAT_FORMAT || defined (REAL_IS_NOT_DOUBLE))
- && GET_MODE_CLASS (GET_MODE (x)) != MODE_FLOAT
-#endif
- )
- return GEN_INT (CONST_DOUBLE_HIGH (x) & GET_MODE_MASK (mode));
- else if (GET_CODE (x) == CONST_INT)
- {
- if (HOST_BITS_PER_WIDE_INT <= BITS_PER_WORD)
- return const0_rtx;
- return GEN_INT (INTVAL (x) >> (HOST_BITS_PER_WIDE_INT - BITS_PER_WORD));
- }
- else if (GET_CODE (x) == MEM)
- {
- register int offset = 0;
- if (! WORDS_BIG_ENDIAN)
- offset = (MAX (xsize, UNITS_PER_WORD)
- - MAX (msize, UNITS_PER_WORD));
+ result = simplify_gen_subreg (mode, x, GET_MODE (x),
+ subreg_highpart_offset (mode, GET_MODE (x)));
+ if (!result)
+ abort ();
+ return result;
+}
+/* Return offset in bytes to get OUTERMODE low part
+ of the value in mode INNERMODE stored in memory in target format. */
- if (! BYTES_BIG_ENDIAN
- && msize < UNITS_PER_WORD)
- offset -= (msize - MIN (UNITS_PER_WORD, xsize));
+unsigned int
+subreg_lowpart_offset (outermode, innermode)
+ enum machine_mode outermode, innermode;
+{
+ unsigned int offset = 0;
+ int difference = (GET_MODE_SIZE (innermode) - GET_MODE_SIZE (outermode));
- return change_address (x, mode, plus_constant (XEXP (x, 0), offset));
- }
- else if (GET_CODE (x) == SUBREG)
+ if (difference > 0)
{
- /* The only time this should occur is when we are looking at a
- multi-word item with a SUBREG whose mode is the same as that of the
- item. It isn't clear what we would do if it wasn't. */
- if (SUBREG_BYTE (x) != 0)
- abort ();
- return gen_highpart (mode, SUBREG_REG (x));
+ if (WORDS_BIG_ENDIAN)
+ offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
+ if (BYTES_BIG_ENDIAN)
+ offset += difference % UNITS_PER_WORD;
}
- else if (GET_CODE (x) == REG)
- {
- int offset = 0;
-
- if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (mode))
- abort ();
-
- if ((! WORDS_BIG_ENDIAN || ! BYTES_BIG_ENDIAN)
- && xsize > msize)
- {
- int difference = xsize - msize;
- if (! WORDS_BIG_ENDIAN)
- offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
- if (! BYTES_BIG_ENDIAN)
- offset += difference % UNITS_PER_WORD;
- }
- if (REGNO (x) < FIRST_PSEUDO_REGISTER)
- {
- int final_regno = REGNO (x) +
- subreg_regno_offset (REGNO (x), GET_MODE (x), offset, mode);
-
- /* integrate.c can't handle parts of a return value register.
- ??? Then integrate.c should be fixed!
- ??? What about CLASS_CANNOT_CHANGE_SIZE? */
- if ((! REG_FUNCTION_VALUE_P (x)
- || ! rtx_equal_function_value_matters)
- /* We want to keep the stack, frame, and arg pointers special. */
- && x != frame_pointer_rtx
-#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
- && x != arg_pointer_rtx
-#endif
- && x != stack_pointer_rtx)
- return gen_rtx_REG (mode, final_regno);
- }
- /* Just generate a normal SUBREG. */
- return gen_rtx_SUBREG (mode, x, offset);
- }
- else
- abort ();
+ return offset;
}
-/* Return 1 iff (SUBREG:outermode (OP:innermode) byte)
- refers to the least significant part of its containing reg. */
-int
-subreg_lowpart_parts_p (outermode, innermode, byte)
+/* Return offset in bytes to get OUTERMODE high part
+ of the value in mode INNERMODE stored in memory in target format. */
+unsigned int
+subreg_highpart_offset (outermode, innermode)
enum machine_mode outermode, innermode;
- unsigned int byte;
{
unsigned int offset = 0;
int difference = (GET_MODE_SIZE (innermode) - GET_MODE_SIZE (outermode));
+ if (GET_MODE_SIZE (innermode) < GET_MODE_SIZE (outermode))
+ abort ();
+
if (difference > 0)
{
- if (WORDS_BIG_ENDIAN)
+ if (! WORDS_BIG_ENDIAN)
offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
- if (BYTES_BIG_ENDIAN)
+ if (! BYTES_BIG_ENDIAN)
offset += difference % UNITS_PER_WORD;
}
- return byte == offset;
+ return offset;
}
/* Return 1 iff X, assumed to be a SUBREG,
@@ -1313,8 +1190,8 @@ subreg_lowpart_p (x)
else if (GET_MODE (SUBREG_REG (x)) == VOIDmode)
return 0;
- return subreg_lowpart_parts_p (GET_MODE (x), GET_MODE (SUBREG_REG (x)),
- SUBREG_BYTE (x));
+ return (subreg_lowpart_offset (GET_MODE (x), GET_MODE (SUBREG_REG (x)))
+ == SUBREG_BYTE (x));
}
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 648aa13..1cc0d73 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1198,9 +1198,10 @@ extern rtx constant_subword PARAMS ((rtx, int,
extern rtx operand_subword_force PARAMS ((rtx, unsigned int,
enum machine_mode));
extern int subreg_lowpart_p PARAMS ((rtx));
-extern int subreg_lowpart_parts_p PARAMS ((enum machine_mode,
- enum machine_mode,
- unsigned int));
+extern unsigned int subreg_lowpart_offset PARAMS ((enum machine_mode,
+ enum machine_mode));
+extern unsigned int subreg_highpart_offset PARAMS ((enum machine_mode,
+ enum machine_mode));
extern rtx make_safe_from PARAMS ((rtx, rtx));
extern rtx convert_memory_address PARAMS ((enum machine_mode, rtx));
extern rtx get_insns PARAMS ((void));
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index af0f81f..0f0f6cd 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -2258,40 +2258,9 @@ replace_regs (x, reg_map, nregs, replace_dest)
&& GET_CODE (reg_map[REGNO (SUBREG_REG (x))]) == SUBREG)
{
rtx map_val = reg_map[REGNO (SUBREG_REG (x))];
- rtx map_inner = SUBREG_REG (map_val);
-
- if (GET_MODE (x) == GET_MODE (map_inner))
- return map_inner;
- else
- {
- int final_offset = SUBREG_BYTE (x) + SUBREG_BYTE (map_val);
-
- /* When working with REG SUBREGs the rule is that the byte
- offset must be a multiple of the SUBREG's mode. */
- final_offset = (final_offset / GET_MODE_SIZE (GET_MODE (x)));
- final_offset = (final_offset * GET_MODE_SIZE (GET_MODE (x)));
-
- /* We cannot call gen_rtx here since we may be linked with
- genattrtab.c. */
- /* Let's try clobbering the incoming SUBREG and see
- if this is really safe. */
- SUBREG_REG (x) = map_inner;
- SUBREG_BYTE (x) = final_offset;
- return x;
-#if 0
- rtx new = rtx_alloc (SUBREG);
- int final_offset = SUBREG_BYTE (x) + SUBREG_BYTE (map_val);
-
- /* When working with REG SUBREGs the rule is that the byte
- offset must be a multiple of the SUBREG's mode. */
- final_offset = (final_offset / GET_MODE_SIZE (GET_MODE (x)));
- final_offset = (final_offset * GET_MODE_SIZE (GET_MODE (x)));
-
- PUT_MODE (new, GET_MODE (x));
- SUBREG_REG (new) = map_inner;
- SUBREG_BYTE (new) = final_offset;
-#endif
- }
+ return simplify_gen_subreg (GET_MODE (x), map_val,
+ GET_MODE (SUBREG_REG (x)),
+ SUBREG_BYTE (x));
}
break;
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 621bd90..aef9b55 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -2215,7 +2215,7 @@ 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_parts_p (outermode, innermode, byte))
+ if (subreg_lowpart_offset (outermode, innermode) == byte)
{
rtx new = gen_lowpart_if_possible (outermode, op);
if (new)
@@ -2347,11 +2347,23 @@ simplify_subreg (outermode, op, innermode, byte)
frame, or argument pointer, leave this as a SUBREG. */
if (REG_P (op)
+ && (! REG_FUNCTION_VALUE_P (op)
+ || ! rtx_equal_function_value_matters)
+#ifdef CLASS_CANNOT_CHANGE_MODE
+ && ! (CLASS_CANNOT_CHANGE_MODE_P (outermode, innermode)
+ && GET_MODE_CLASS (innermode) != MODE_COMPLEX_INT
+ && GET_MODE_CLASS (innermode) != MODE_COMPLEX_FLOAT
+ && (TEST_HARD_REG_BIT
+ (reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE],
+ REGNO (op))))
+#endif
&& REGNO (op) < FIRST_PSEUDO_REGISTER
- && REGNO (op) != FRAME_POINTER_REGNUM
+ && ((reload_completed && !frame_pointer_needed)
+ || (REGNO (op) != FRAME_POINTER_REGNUM
#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
- && REGNO (op) != HARD_FRAME_POINTER_REGNUM
+ && REGNO (op) != HARD_FRAME_POINTER_REGNUM
#endif
+ ))
#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
&& REGNO (op) != ARG_POINTER_REGNUM
#endif
@@ -2360,7 +2372,11 @@ simplify_subreg (outermode, op, innermode, byte)
int final_regno = subreg_hard_regno (gen_rtx_SUBREG (outermode, op, byte),
0);
- if (HARD_REGNO_MODE_OK (final_regno, outermode))
+ /* ??? We do allow it if the current REG is not valid for
+ its mode. This is a kludge to work around how float/complex
+ arguments are passed on 32-bit Sparc and should be fixed. */
+ if (HARD_REGNO_MODE_OK (final_regno, outermode)
+ || ! HARD_REGNO_MODE_OK (REGNO (op), innermode))
return gen_rtx_REG (outermode, final_regno);
}