Commit e0e08ac2 by Jan Hubicka Committed by Jan Hubicka

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
parent 95307c8e
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> Mon Jun 4 09:21:19 2001 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* tree.def (ARRAY_RANGE_REF): New code. * tree.def (ARRAY_RANGE_REF): New code.
......
...@@ -3715,7 +3715,7 @@ combine_simplify_rtx (x, op0_mode, last, in_dest) ...@@ -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 /* If CODE is an associative operation not otherwise handled, see if we
can associate some operands. This can win if they are constants or 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 if ((code == PLUS || code == MINUS
|| code == MULT || code == AND || code == IOR || code == XOR || code == MULT || code == AND || code == IOR || code == XOR
|| code == DIV || code == UDIV || code == DIV || code == UDIV
...@@ -3774,7 +3774,7 @@ combine_simplify_rtx (x, op0_mode, last, in_dest) ...@@ -3774,7 +3774,7 @@ combine_simplify_rtx (x, op0_mode, last, in_dest)
/* simplify_subreg can't use gen_lowpart_for_combine. */ /* simplify_subreg can't use gen_lowpart_for_combine. */
if (CONSTANT_P (SUBREG_REG (x)) 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)); return gen_lowpart_for_combine (mode, SUBREG_REG (x));
{ {
...@@ -9765,18 +9765,13 @@ gen_lowpart_for_combine (mode, x) ...@@ -9765,18 +9765,13 @@ gen_lowpart_for_combine (mode, x)
else else
{ {
int offset = 0; int offset = 0;
rtx res;
if ((WORDS_BIG_ENDIAN || BYTES_BIG_ENDIAN) offset = subreg_lowpart_offset (mode, GET_MODE (x));
&& GET_MODE_SIZE (GET_MODE (x)) > GET_MODE_SIZE (mode)) res = simplify_gen_subreg (mode, x, GET_MODE (x), offset);
{ if (res)
int difference = (GET_MODE_SIZE (GET_MODE (x)) return res;
- GET_MODE_SIZE (mode)); return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
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);
} }
} }
......
...@@ -381,22 +381,12 @@ gen_lowpart_SUBREG (mode, reg) ...@@ -381,22 +381,12 @@ gen_lowpart_SUBREG (mode, reg)
rtx reg; rtx reg;
{ {
enum machine_mode inmode; enum machine_mode inmode;
int offset;
inmode = GET_MODE (reg); inmode = GET_MODE (reg);
if (inmode == VOIDmode) if (inmode == VOIDmode)
inmode = mode; inmode = mode;
offset = 0; return gen_rtx_SUBREG (mode, reg,
if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (inmode) subreg_lowpart_offset (mode, 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);
} }
/* rtx gen_rtx (code, mode, [element1, ..., elementn]) /* rtx gen_rtx (code, mode, [element1, ..., elementn])
...@@ -761,16 +751,7 @@ gen_lowpart_common (mode, x) ...@@ -761,16 +751,7 @@ gen_lowpart_common (mode, x)
> ((xsize + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))) > ((xsize + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)))
return 0; return 0;
if ((WORDS_BIG_ENDIAN || BYTES_BIG_ENDIAN) offset = subreg_lowpart_offset (mode, GET_MODE (x));
&& 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 ((GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND) if ((GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND)
&& (GET_MODE_CLASS (mode) == MODE_INT && (GET_MODE_CLASS (mode) == MODE_INT
...@@ -791,61 +772,8 @@ gen_lowpart_common (mode, x) ...@@ -791,61 +772,8 @@ gen_lowpart_common (mode, x)
else if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_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)); return gen_rtx_fmt_e (GET_CODE (x), mode, XEXP (x, 0));
} }
else if (GET_CODE (x) == SUBREG else if (GET_CODE (x) == SUBREG || GET_CODE (x) == REG || GET_CODE (x) == CONCAT)
&& (GET_MODE_SIZE (mode) <= UNITS_PER_WORD return simplify_gen_subreg (mode, x, GET_MODE (x), offset);
|| 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);
}
/* If X is a CONST_INT or a CONST_DOUBLE, extract the appropriate bits /* If X is a CONST_INT or a CONST_DOUBLE, extract the appropriate bits
from the low-order part of the constant. */ from the low-order part of the constant. */
else if ((GET_MODE_CLASS (mode) == MODE_INT else if ((GET_MODE_CLASS (mode) == MODE_INT
...@@ -1088,12 +1016,10 @@ gen_realpart (mode, x) ...@@ -1088,12 +1016,10 @@ gen_realpart (mode, x)
enum machine_mode mode; enum machine_mode mode;
register rtx x; register rtx x;
{ {
if (GET_CODE (x) == CONCAT && GET_MODE (XEXP (x, 0)) == mode) if (WORDS_BIG_ENDIAN
return XEXP (x, 0); && GET_MODE_BITSIZE (mode) < BITS_PER_WORD
else if (WORDS_BIG_ENDIAN && REG_P (x)
&& GET_MODE_BITSIZE (mode) < BITS_PER_WORD && REGNO (x) < FIRST_PSEUDO_REGISTER)
&& REG_P (x)
&& REGNO (x) < FIRST_PSEUDO_REGISTER)
internal_error internal_error
("Can't access real part of complex value in hard register"); ("Can't access real part of complex value in hard register");
else if (WORDS_BIG_ENDIAN) else if (WORDS_BIG_ENDIAN)
...@@ -1110,9 +1036,7 @@ gen_imagpart (mode, x) ...@@ -1110,9 +1036,7 @@ gen_imagpart (mode, x)
enum machine_mode mode; enum machine_mode mode;
register rtx x; register rtx x;
{ {
if (GET_CODE (x) == CONCAT && GET_MODE (XEXP (x, 0)) == mode) if (WORDS_BIG_ENDIAN)
return XEXP (x, 1);
else if (WORDS_BIG_ENDIAN)
return gen_lowpart (mode, x); return gen_lowpart (mode, x);
else if (! WORDS_BIG_ENDIAN else if (! WORDS_BIG_ENDIAN
&& GET_MODE_BITSIZE (mode) < BITS_PER_WORD && GET_MODE_BITSIZE (mode) < BITS_PER_WORD
...@@ -1195,109 +1119,62 @@ gen_highpart (mode, x) ...@@ -1195,109 +1119,62 @@ gen_highpart (mode, x)
register rtx x; register rtx x;
{ {
unsigned int msize = GET_MODE_SIZE (mode); 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, /* This case loses if X is a subreg. To catch bugs early,
complain if an invalid MODE is used even in other cases. */ complain if an invalid MODE is used even in other cases. */
if (msize > UNITS_PER_WORD if (msize > UNITS_PER_WORD
&& msize != GET_MODE_UNIT_SIZE (GET_MODE (x))) && msize != GET_MODE_UNIT_SIZE (GET_MODE (x)))
abort (); 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) result = simplify_gen_subreg (mode, x, GET_MODE (x),
offset = (MAX (xsize, UNITS_PER_WORD) subreg_highpart_offset (mode, GET_MODE (x)));
- MAX (msize, UNITS_PER_WORD)); 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 unsigned int
&& msize < UNITS_PER_WORD) subreg_lowpart_offset (outermode, innermode)
offset -= (msize - MIN (UNITS_PER_WORD, xsize)); 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)); if (difference > 0)
}
else if (GET_CODE (x) == SUBREG)
{ {
/* The only time this should occur is when we are looking at a if (WORDS_BIG_ENDIAN)
multi-word item with a SUBREG whose mode is the same as that of the offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
item. It isn't clear what we would do if it wasn't. */ if (BYTES_BIG_ENDIAN)
if (SUBREG_BYTE (x) != 0) offset += difference % UNITS_PER_WORD;
abort ();
return gen_highpart (mode, SUBREG_REG (x));
} }
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) return offset;
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 1 iff (SUBREG:outermode (OP:innermode) byte)
refers to the least significant part of its containing reg. */
int /* Return offset in bytes to get OUTERMODE high part
subreg_lowpart_parts_p (outermode, innermode, byte) of the value in mode INNERMODE stored in memory in target format. */
unsigned int
subreg_highpart_offset (outermode, innermode)
enum machine_mode outermode, innermode; enum machine_mode outermode, innermode;
unsigned int byte;
{ {
unsigned int offset = 0; unsigned int offset = 0;
int difference = (GET_MODE_SIZE (innermode) - GET_MODE_SIZE (outermode)); int difference = (GET_MODE_SIZE (innermode) - GET_MODE_SIZE (outermode));
if (GET_MODE_SIZE (innermode) < GET_MODE_SIZE (outermode))
abort ();
if (difference > 0) if (difference > 0)
{ {
if (WORDS_BIG_ENDIAN) if (! WORDS_BIG_ENDIAN)
offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD; offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
if (BYTES_BIG_ENDIAN) if (! BYTES_BIG_ENDIAN)
offset += difference % UNITS_PER_WORD; offset += difference % UNITS_PER_WORD;
} }
return byte == offset; return offset;
} }
/* Return 1 iff X, assumed to be a SUBREG, /* Return 1 iff X, assumed to be a SUBREG,
...@@ -1313,8 +1190,8 @@ subreg_lowpart_p (x) ...@@ -1313,8 +1190,8 @@ subreg_lowpart_p (x)
else if (GET_MODE (SUBREG_REG (x)) == VOIDmode) else if (GET_MODE (SUBREG_REG (x)) == VOIDmode)
return 0; return 0;
return subreg_lowpart_parts_p (GET_MODE (x), GET_MODE (SUBREG_REG (x)), return (subreg_lowpart_offset (GET_MODE (x), GET_MODE (SUBREG_REG (x)))
SUBREG_BYTE (x)); == SUBREG_BYTE (x));
} }
......
...@@ -1198,9 +1198,10 @@ extern rtx constant_subword PARAMS ((rtx, int, ...@@ -1198,9 +1198,10 @@ extern rtx constant_subword PARAMS ((rtx, int,
extern rtx operand_subword_force PARAMS ((rtx, unsigned int, extern rtx operand_subword_force PARAMS ((rtx, unsigned int,
enum machine_mode)); enum machine_mode));
extern int subreg_lowpart_p PARAMS ((rtx)); extern int subreg_lowpart_p PARAMS ((rtx));
extern int subreg_lowpart_parts_p PARAMS ((enum machine_mode, extern unsigned int subreg_lowpart_offset PARAMS ((enum machine_mode,
enum machine_mode, enum machine_mode));
unsigned int)); extern unsigned int subreg_highpart_offset PARAMS ((enum machine_mode,
enum machine_mode));
extern rtx make_safe_from PARAMS ((rtx, rtx)); extern rtx make_safe_from PARAMS ((rtx, rtx));
extern rtx convert_memory_address PARAMS ((enum machine_mode, rtx)); extern rtx convert_memory_address PARAMS ((enum machine_mode, rtx));
extern rtx get_insns PARAMS ((void)); extern rtx get_insns PARAMS ((void));
......
...@@ -2258,40 +2258,9 @@ replace_regs (x, reg_map, nregs, replace_dest) ...@@ -2258,40 +2258,9 @@ replace_regs (x, reg_map, nregs, replace_dest)
&& GET_CODE (reg_map[REGNO (SUBREG_REG (x))]) == SUBREG) && GET_CODE (reg_map[REGNO (SUBREG_REG (x))]) == SUBREG)
{ {
rtx map_val = reg_map[REGNO (SUBREG_REG (x))]; rtx map_val = reg_map[REGNO (SUBREG_REG (x))];
rtx map_inner = SUBREG_REG (map_val); return simplify_gen_subreg (GET_MODE (x), map_val,
GET_MODE (SUBREG_REG (x)),
if (GET_MODE (x) == GET_MODE (map_inner)) SUBREG_BYTE (x));
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
}
} }
break; break;
......
...@@ -2215,7 +2215,7 @@ simplify_subreg (outermode, op, innermode, byte) ...@@ -2215,7 +2215,7 @@ simplify_subreg (outermode, op, innermode, byte)
Later it we should move all simplification code here and rewrite Later it we should move all simplification code here and rewrite
GEN_LOWPART_IF_POSSIBLE, GEN_HIGHPART, OPERAND_SUBWORD and friends GEN_LOWPART_IF_POSSIBLE, GEN_HIGHPART, OPERAND_SUBWORD and friends
using SIMPLIFY_SUBREG. */ 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); rtx new = gen_lowpart_if_possible (outermode, op);
if (new) if (new)
...@@ -2347,11 +2347,23 @@ simplify_subreg (outermode, op, innermode, byte) ...@@ -2347,11 +2347,23 @@ simplify_subreg (outermode, op, innermode, byte)
frame, or argument pointer, leave this as a SUBREG. */ frame, or argument pointer, leave this as a SUBREG. */
if (REG_P (op) 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) < 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 #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
&& REGNO (op) != HARD_FRAME_POINTER_REGNUM && REGNO (op) != HARD_FRAME_POINTER_REGNUM
#endif #endif
))
#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
&& REGNO (op) != ARG_POINTER_REGNUM && REGNO (op) != ARG_POINTER_REGNUM
#endif #endif
...@@ -2360,7 +2372,11 @@ simplify_subreg (outermode, op, innermode, byte) ...@@ -2360,7 +2372,11 @@ simplify_subreg (outermode, op, innermode, byte)
int final_regno = subreg_hard_regno (gen_rtx_SUBREG (outermode, op, byte), int final_regno = subreg_hard_regno (gen_rtx_SUBREG (outermode, op, byte),
0); 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); return gen_rtx_REG (outermode, final_regno);
} }
......
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