Commit 7a32a925 by Richard Henderson Committed by Richard Henderson

combine.c (gen_lowpart_for_combine): Factor out mode of x as well as mode sizes…

combine.c (gen_lowpart_for_combine): Factor out mode of x as well as mode sizes into local temporaries.

        * combine.c (gen_lowpart_for_combine): Factor out mode of x as well
        as mode sizes into local temporaries.  Unify failure path.

From-SVN: r91118
parent b5b3e36a
...@@ -16,6 +16,11 @@ ...@@ -16,6 +16,11 @@
2004-11-23 Richard Henderson <rth@redhat.com> 2004-11-23 Richard Henderson <rth@redhat.com>
* combine.c (gen_lowpart_for_combine): Factor out mode of x as well
as mode sizes into local temporaries. Unify failure path.
2004-11-23 Richard Henderson <rth@redhat.com>
* emit-rtl.c, rtl.h (subreg_hard_regno): Remove. * emit-rtl.c, rtl.h (subreg_hard_regno): Remove.
* caller-save.c (mark_set_regs): Use subreg_regno instead. * caller-save.c (mark_set_regs): Use subreg_regno instead.
* final.c (alter_subreg): Likewise. * final.c (alter_subreg): Likewise.
......
...@@ -9308,16 +9308,18 @@ recog_for_combine (rtx *pnewpat, rtx insn, rtx *pnotes) ...@@ -9308,16 +9308,18 @@ recog_for_combine (rtx *pnewpat, rtx insn, rtx *pnotes)
An insn containing that will not be recognized. */ An insn containing that will not be recognized. */
static rtx static rtx
gen_lowpart_for_combine (enum machine_mode mode, rtx x) gen_lowpart_for_combine (enum machine_mode omode, rtx x)
{ {
enum machine_mode imode = GET_MODE (x);
unsigned int osize = GET_MODE_SIZE (omode);
unsigned int isize = GET_MODE_SIZE (imode);
rtx result; rtx result;
if (GET_MODE (x) == mode) if (omode == imode)
return x; return x;
/* Return identity if this is a CONST or symbolic /* Return identity if this is a CONST or symbolic reference. */
reference. */ if (omode == Pmode
if (mode == Pmode
&& (GET_CODE (x) == CONST && (GET_CODE (x) == CONST
|| GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == SYMBOL_REF
|| GET_CODE (x) == LABEL_REF)) || GET_CODE (x) == LABEL_REF))
...@@ -9325,13 +9327,12 @@ gen_lowpart_for_combine (enum machine_mode mode, rtx x) ...@@ -9325,13 +9327,12 @@ gen_lowpart_for_combine (enum machine_mode mode, rtx x)
/* We can only support MODE being wider than a word if X is a /* We can only support MODE being wider than a word if X is a
constant integer or has a mode the same size. */ constant integer or has a mode the same size. */
if (GET_MODE_SIZE (omode) > UNITS_PER_WORD
if (GET_MODE_SIZE (mode) > UNITS_PER_WORD && ! ((imode == VOIDmode
&& ! ((GET_MODE (x) == VOIDmode
&& (GET_CODE (x) == CONST_INT && (GET_CODE (x) == CONST_INT
|| GET_CODE (x) == CONST_DOUBLE)) || GET_CODE (x) == CONST_DOUBLE))
|| GET_MODE_SIZE (GET_MODE (x)) == GET_MODE_SIZE (mode))) || isize == osize))
return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx); goto fail;
/* X might be a paradoxical (subreg (mem)). In that case, gen_lowpart /* X might be a paradoxical (subreg (mem)). In that case, gen_lowpart
won't know what to do. So we will strip off the SUBREG here and won't know what to do. So we will strip off the SUBREG here and
...@@ -9339,11 +9340,12 @@ gen_lowpart_for_combine (enum machine_mode mode, rtx x) ...@@ -9339,11 +9340,12 @@ gen_lowpart_for_combine (enum machine_mode mode, rtx x)
if (GET_CODE (x) == SUBREG && MEM_P (SUBREG_REG (x))) if (GET_CODE (x) == SUBREG && MEM_P (SUBREG_REG (x)))
{ {
x = SUBREG_REG (x); x = SUBREG_REG (x);
if (GET_MODE (x) == mode) if (GET_MODE (x) == omode)
return x; return x;
} }
result = gen_lowpart_common (mode, x); result = gen_lowpart_common (omode, x);
#ifdef CANNOT_CHANGE_MODE_CLASS #ifdef CANNOT_CHANGE_MODE_CLASS
if (result != 0 && GET_CODE (result) == SUBREG) if (result != 0 && GET_CODE (result) == SUBREG)
record_subregs_of_mode (result); record_subregs_of_mode (result);
...@@ -9359,33 +9361,28 @@ gen_lowpart_for_combine (enum machine_mode mode, rtx x) ...@@ -9359,33 +9361,28 @@ gen_lowpart_for_combine (enum machine_mode mode, rtx x)
/* Refuse to work on a volatile memory ref or one with a mode-dependent /* Refuse to work on a volatile memory ref or one with a mode-dependent
address. */ address. */
if (MEM_VOLATILE_P (x) || mode_dependent_address_p (XEXP (x, 0))) if (MEM_VOLATILE_P (x) || mode_dependent_address_p (XEXP (x, 0)))
return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx); goto fail;
/* If we want to refer to something bigger than the original memref, /* If we want to refer to something bigger than the original memref,
generate a paradoxical subreg instead. That will force a reload generate a paradoxical subreg instead. That will force a reload
of the original memref X. */ of the original memref X. */
if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (mode)) if (isize < osize)
return gen_rtx_SUBREG (mode, x, 0); return gen_rtx_SUBREG (omode, x, 0);
if (WORDS_BIG_ENDIAN) if (WORDS_BIG_ENDIAN)
offset = (MAX (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD) offset = MAX (isize, UNITS_PER_WORD) - MAX (osize, UNITS_PER_WORD);
- MAX (GET_MODE_SIZE (mode), UNITS_PER_WORD));
/* Adjust the address so that the address-after-the-data is unchanged. */
if (BYTES_BIG_ENDIAN) if (BYTES_BIG_ENDIAN)
{ offset -= MIN (UNITS_PER_WORD, osize) - MIN (UNITS_PER_WORD, isize);
/* Adjust the address so that the address-after-the-data is
unchanged. */
offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode))
- MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x))));
}
return adjust_address_nv (x, mode, offset); return adjust_address_nv (x, omode, offset);
} }
/* If X is a comparison operator, rewrite it in a new mode. This /* If X is a comparison operator, rewrite it in a new mode. This
probably won't match, but may allow further simplifications. */ probably won't match, but may allow further simplifications. */
else if (COMPARISON_P (x)) else if (COMPARISON_P (x))
return gen_rtx_fmt_ee (GET_CODE (x), mode, XEXP (x, 0), XEXP (x, 1)); return gen_rtx_fmt_ee (GET_CODE (x), omode, XEXP (x, 0), XEXP (x, 1));
/* If we couldn't simplify X any other way, just enclose it in a /* If we couldn't simplify X any other way, just enclose it in a
SUBREG. Normally, this SUBREG won't match, but some patterns may SUBREG. Normally, this SUBREG won't match, but some patterns may
...@@ -9394,21 +9391,22 @@ gen_lowpart_for_combine (enum machine_mode mode, rtx x) ...@@ -9394,21 +9391,22 @@ gen_lowpart_for_combine (enum machine_mode mode, rtx x)
{ {
int offset = 0; int offset = 0;
rtx res; rtx res;
enum machine_mode sub_mode = GET_MODE (x);
offset = subreg_lowpart_offset (mode, sub_mode); offset = subreg_lowpart_offset (omode, imode);
if (sub_mode == VOIDmode) if (imode == VOIDmode)
{ {
sub_mode = int_mode_for_mode (mode); imode = int_mode_for_mode (omode);
x = gen_lowpart_common (sub_mode, x); x = gen_lowpart_common (imode, x);
if (x == 0) if (x == NULL)
return gen_rtx_CLOBBER (VOIDmode, const0_rtx); goto fail;
} }
res = simplify_gen_subreg (mode, x, sub_mode, offset); res = simplify_gen_subreg (omode, x, imode, offset);
if (res) if (res)
return res; return res;
return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
} }
fail:
return gen_rtx_CLOBBER (imode, const0_rtx);
} }
/* These routines make binary and unary operations by first seeing if they /* These routines make binary and unary operations by first seeing if they
......
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