diff options
author | Joseph Myers <joseph@codesourcery.com> | 2009-03-04 01:57:29 +0000 |
---|---|---|
committer | Joseph Myers <jsm28@gcc.gnu.org> | 2009-03-04 01:57:29 +0000 |
commit | a6fe9ed43e2cb62e8616dbb825172b9e9db7ed98 (patch) | |
tree | 09145ea9afe18888cc75a7347dcca1bd063003f5 /gcc/emit-rtl.c | |
parent | dd7d0a4f8f91b346bb409b70a53351517668952f (diff) | |
download | gcc-a6fe9ed43e2cb62e8616dbb825172b9e9db7ed98.tar.gz |
emit-rtl.c (adjust_address_1): Reduce offset to a signed value that fits within Pmode.
* emit-rtl.c (adjust_address_1): Reduce offset to a signed value
that fits within Pmode.
testsuite:
* gcc.c-torture/compile/20090303-1.c,
gcc.c-torture/compile/20090303-2.c: New tests.
From-SVN: r144595
Diffstat (limited to 'gcc/emit-rtl.c')
-rw-r--r-- | gcc/emit-rtl.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 679e95ea8a2..ca033824c0d 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -2008,6 +2008,7 @@ adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset, rtx memoffset = MEM_OFFSET (memref); rtx size = 0; unsigned int memalign = MEM_ALIGN (memref); + int pbits; /* If there are no changes, just return the original memory reference. */ if (mode == GET_MODE (memref) && !offset @@ -2019,6 +2020,16 @@ adjust_address_1 (rtx memref, enum machine_mode mode, HOST_WIDE_INT offset, (plus (plus reg reg) const_int) -- so do this always. */ addr = copy_rtx (addr); + /* Convert a possibly large offset to a signed value within the + range of the target address space. */ + pbits = GET_MODE_BITSIZE (Pmode); + if (HOST_BITS_PER_WIDE_INT > pbits) + { + int shift = HOST_BITS_PER_WIDE_INT - pbits; + offset = (((HOST_WIDE_INT) ((unsigned HOST_WIDE_INT) offset << shift)) + >> shift); + } + if (adjust) { /* If MEMREF is a LO_SUM and the offset is within the alignment of the |