diff options
author | Richard Sandiford <richard.sandiford@linaro.org> | 2017-09-04 10:48:40 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2017-09-04 10:48:40 +0000 |
commit | 3d09ba95c150d9676f9a2585fb61315e86fa644a (patch) | |
tree | 6c37f118811f8cff123ef56870a20145fd74b472 /gcc/emit-rtl.c | |
parent | d8c40eff56f69877b33c697ded756d50fde90c27 (diff) | |
download | gcc-3d09ba95c150d9676f9a2585fb61315e86fa644a.zip gcc-3d09ba95c150d9676f9a2585fb61315e86fa644a.tar.gz gcc-3d09ba95c150d9676f9a2585fb61315e86fa644a.tar.bz2 |
Add subreg_memory_offset helper functions
This patch adds routines for converting a SUBREG_BYTE offset into a
memory address offset. The two only differ for paradoxical subregs,
where SUBREG_BYTE is always 0 but the memory address offset can be
negative.
2017-09-04 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
gcc/
* rtl.h (subreg_memory_offset): Declare.
* emit-rtl.c (subreg_memory_offset): New function.
* expmed.c (store_bit_field_1): Use it.
* expr.c (undefined_operand_subword_p): Likewise.
* simplify-rtx.c (simplify_subreg): Likewise.
Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r251644
Diffstat (limited to 'gcc/emit-rtl.c')
-rw-r--r-- | gcc/emit-rtl.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 3954648..ac6637d 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -1005,6 +1005,33 @@ byte_lowpart_offset (machine_mode outer_mode, else return subreg_lowpart_offset (outer_mode, inner_mode); } + +/* Return the offset of (subreg:OUTER_MODE (mem:INNER_MODE X) OFFSET) + from address X. For paradoxical big-endian subregs this is a + negative value, otherwise it's the same as OFFSET. */ + +int +subreg_memory_offset (machine_mode outer_mode, machine_mode inner_mode, + unsigned int offset) +{ + if (paradoxical_subreg_p (outer_mode, inner_mode)) + { + gcc_assert (offset == 0); + return -subreg_lowpart_offset (inner_mode, outer_mode); + } + return offset; +} + +/* As above, but return the offset that existing subreg X would have + if SUBREG_REG (X) were stored in memory. The only significant thing + about the current SUBREG_REG is its mode. */ + +int +subreg_memory_offset (const_rtx x) +{ + return subreg_memory_offset (GET_MODE (x), GET_MODE (SUBREG_REG (x)), + SUBREG_BYTE (x)); +} /* Generate a REG rtx for a new pseudo register of mode MODE. This pseudo is assigned the next sequential register number. */ |