This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
subreg related cleanups
- To: gcc-patches at gcc dot gnu dot org, patches at x86-64 dot org, rth at cygnus dot com, kenner at vlsi1 dot ultra dot nyu dot edu
- Subject: subreg related cleanups
- From: Jan Hubicka <jh at suse dot cz>
- Date: Thu, 24 May 2001 15:40:53 +0200
Hi
This patch adds subreg_lowpart_offset and subreg_highpart_offset
just to avoid complex expressions copied all around the sources.
Bootstrapped+regtested on i386.
Honza
Thu May 24 15:36:35 CEST 2001 Jan Hubicka <jh@suse.cz>
* 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.
Index: combine.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/combine.c,v
retrieving revision 1.205
diff -c -3 -p -r1.205 combine.c
*** combine.c 2001/05/22 07:40:24 1.205
--- combine.c 2001/05/24 12:57:59
*************** combine_simplify_rtx (x, op0_mode, last,
*** 3715,3721 ****
/* 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 ((code == PLUS || code == MINUS
|| code == MULT || code == AND || code == IOR || code == XOR
|| code == DIV || code == UDIV
--- 3715,3721 ----
/* 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 ((code == PLUS || code == MINUS
|| code == MULT || code == AND || code == IOR || code == XOR
|| code == DIV || code == UDIV
*************** combine_simplify_rtx (x, op0_mode, last,
*** 3774,3780 ****
/* 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)))
return gen_lowpart_for_combine (mode, SUBREG_REG (x));
{
--- 3774,3780 ----
/* simplify_subreg can't use gen_lowpart_for_combine. */
if (CONSTANT_P (SUBREG_REG (x))
! && subreg_lowpart_offset (mode, op0_mode) == SUBREG_BYTE (x))
return gen_lowpart_for_combine (mode, SUBREG_REG (x));
{
*************** gen_lowpart_for_combine (mode, x)
*** 9765,9782 ****
else
{
int offset = 0;
! 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);
}
}
--- 9766,9778 ----
else
{
int offset = 0;
+ rtx res;
! 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);
}
}
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/rtl.h,v
retrieving revision 1.261
diff -c -3 -p -r1.261 rtl.h
*** rtl.h 2001/05/17 21:21:21 1.261
--- rtl.h 2001/05/24 12:58:07
*************** extern rtx constant_subword PARAMS ((rt
*** 1198,1206 ****
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 rtx make_safe_from PARAMS ((rtx, rtx));
extern rtx convert_memory_address PARAMS ((enum machine_mode, rtx));
extern rtx get_insns PARAMS ((void));
--- 1201,1210 ----
extern rtx operand_subword_force PARAMS ((rtx, unsigned int,
enum machine_mode));
extern int subreg_lowpart_p PARAMS ((rtx));
! 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));
Index: simplify-rtx.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/simplify-rtx.c,v
retrieving revision 1.54
diff -c -3 -p -r1.54 simplify-rtx.c
*** simplify-rtx.c 2001/05/22 07:40:26 1.54
--- simplify-rtx.c 2001/05/24 12:58:08
*************** simplify_subreg (outermode, op, innermod
*** 2215,2221 ****
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))
{
rtx new = gen_lowpart_if_possible (outermode, op);
if (new)
--- 2215,2221 ----
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)
{
rtx new = gen_lowpart_if_possible (outermode, op);
if (new)
*** emit-rtl.c Tue May 22 08:29:39 2001
--- emit-rtl.c.highpart Thu May 24 15:34:45 2001
*************** gen_lowpart_SUBREG (mode, reg)
*** 381,402 ****
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);
}
/* rtx gen_rtx (code, mode, [element1, ..., elementn])
--- 381,392 ----
rtx reg;
{
enum machine_mode inmode;
inmode = GET_MODE (reg);
if (inmode == VOIDmode)
inmode = mode;
! return gen_rtx_SUBREG (mode, reg,
! subreg_lowpart_offset (mode, inmode));
}
/* rtx gen_rtx (code, mode, [element1, ..., elementn])
*************** gen_lowpart_common (mode, x)
*** 761,776 ****
> ((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;
! }
if ((GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND)
&& (GET_MODE_CLASS (mode) == MODE_INT
--- 751,757 ----
> ((xsize + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)))
return 0;
! 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
*************** gen_highpart (mode, x)
*** 1278,1290 ****
else
abort ();
}
! /* 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)
enum machine_mode outermode, innermode;
- unsigned int byte;
{
unsigned int offset = 0;
int difference = (GET_MODE_SIZE (innermode) - GET_MODE_SIZE (outermode));
--- 1202,1213 ----
else
abort ();
}
! /* Return offset in bytes to get OUTERMODE low part
! of the value in mode INNERMODE stored in memory in target format. */
! 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));
*************** subreg_lowpart_parts_p (outermode, inner
*** 1297,1303 ****
offset += difference % UNITS_PER_WORD;
}
! return byte == offset;
}
/* Return 1 iff X, assumed to be a SUBREG,
--- 1220,1249 ----
offset += difference % UNITS_PER_WORD;
}
! return offset;
! }
!
! /* 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 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)
! offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD;
! if (! BYTES_BIG_ENDIAN)
! offset += difference % UNITS_PER_WORD;
! }
!
! return offset;
}
/* Return 1 iff X, assumed to be a SUBREG,
*************** subreg_lowpart_p (x)
*** 1313,1320 ****
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));
}
--- 1259,1266 ----
else if (GET_MODE (SUBREG_REG (x)) == VOIDmode)
return 0;
! return (subreg_lowpart_offset (GET_MODE (x), GET_MODE (SUBREG_REG (x)))
! == SUBREG_BYTE (x));
}