diff options
author | David S. Miller <davem@tanya.rutgers.edu> | 1998-01-17 23:08:03 +0000 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 1998-01-17 16:08:03 -0700 |
commit | 0e9ff8854f23cb74cf3620fe4693e344c1c9672e (patch) | |
tree | 2336b25b2cab487594138677cde074a1a6c0ce6d /gcc/combine.c | |
parent | aef28d1d1eb2d3af2b6015c764345724744ee5fe (diff) | |
download | gcc-0e9ff8854f23cb74cf3620fe4693e344c1c9672e.zip gcc-0e9ff8854f23cb74cf3620fe4693e344c1c9672e.tar.gz gcc-0e9ff8854f23cb74cf3620fe4693e344c1c9672e.tar.bz2 |
combine.c (force_to_mode, [...]): Correctly optimize constant offset computations from objects with known...
* combine.c (force_to_mode, nonzero_bits): Correctly optimize
constant offset computations from objects with known alignment in
the presence of STACK_BIAS.
From-SVN: r17405
Diffstat (limited to 'gcc/combine.c')
-rw-r--r-- | gcc/combine.c | 61 |
1 files changed, 51 insertions, 10 deletions
diff --git a/gcc/combine.c b/gcc/combine.c index fc3d688..4bfa9e5 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -6253,12 +6253,32 @@ force_to_mode (x, mode, mask, reg, just_select) smask |= (HOST_WIDE_INT) -1 << width; if (GET_CODE (XEXP (x, 1)) == CONST_INT - && exact_log2 (- smask) >= 0 - && (nonzero_bits (XEXP (x, 0), mode) & ~ mask) == 0 - && (INTVAL (XEXP (x, 1)) & ~ mask) != 0) - return force_to_mode (plus_constant (XEXP (x, 0), - INTVAL (XEXP (x, 1)) & mask), - mode, mask, reg, next_select); + && exact_log2 (- smask) >= 0) + { +#ifdef STACK_BIAS + if (STACK_BIAS + && (XEXP (x, 0) == stack_pointer_rtx + || XEXP (x, 0) == frame_pointer_rtx)) + { + int sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT; + unsigned HOST_WIDE_INT sp_mask = GET_MODE_MASK (mode); + + sp_mask &= ~ (sp_alignment - 1); + if ((sp_mask & ~ mask) == 0 + && ((INTVAL (XEXP (x, 1)) - STACK_BIAS) & ~ mask) != 0) + return force_to_mode (plus_constant (XEXP (x, 0), + ((INTVAL (XEXP (x, 1)) - + STACK_BIAS) & mask) + + STACK_BIAS), + mode, mask, reg, next_select); + } +#endif + if ((nonzero_bits (XEXP (x, 0), mode) & ~ mask) == 0 + && (INTVAL (XEXP (x, 1)) & ~ mask) != 0) + return force_to_mode (plus_constant (XEXP (x, 0), + INTVAL (XEXP (x, 1)) & mask), + mode, mask, reg, next_select); + } } /* ... fall through ... */ @@ -7331,10 +7351,15 @@ nonzero_bits (x, mode) In particular, in the Irix6 n64 ABI, the stack has 128 bit alignment but the argument pointer has only 64 bit alignment. */ - if (x == stack_pointer_rtx || x == frame_pointer_rtx - || x == hard_frame_pointer_rtx - || (REGNO (x) >= FIRST_VIRTUAL_REGISTER - && REGNO (x) <= LAST_VIRTUAL_REGISTER)) + if ((x == frame_pointer_rtx + || x == stack_pointer_rtx + || x == hard_frame_pointer_rtx + || (REGNO (x) >= FIRST_VIRTUAL_REGISTER + && REGNO (x) <= LAST_VIRTUAL_REGISTER)) +#ifdef STACK_BIAS + && !STACK_BIAS +#endif + ) { int sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT; @@ -7515,6 +7540,22 @@ nonzero_bits (x, mode) switch (code) { case PLUS: +#ifdef STACK_BIAS + if (STACK_BIAS + && (XEXP (x, 0) == stack_pointer_rtx + || XEXP (x, 0) == frame_pointer_rtx) + && GET_CODE (XEXP (x, 1)) == CONST_INT) + { + int sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT; + + nz0 = (GET_MODE_MASK (mode) & ~ (sp_alignment - 1)); + nz1 = INTVAL (XEXP (x, 1)) - STACK_BIAS; + width0 = floor_log2 (nz0) + 1; + width1 = floor_log2 (nz1) + 1; + low0 = floor_log2 (nz0 & -nz0); + low1 = floor_log2 (nz1 & -nz1); + } +#endif result_width = MAX (width0, width1) + 1; result_low = MIN (low0, low1); break; |