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/expr.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/expr.c')
-rw-r--r-- | gcc/expr.c | 26 |
1 files changed, 4 insertions, 22 deletions
@@ -3541,30 +3541,12 @@ emit_move_ccmode (machine_mode mode, rtx x, rtx y) static bool undefined_operand_subword_p (const_rtx op, int i) { - machine_mode innermode, innermostmode; - int offset; if (GET_CODE (op) != SUBREG) return false; - innermode = GET_MODE (op); - innermostmode = GET_MODE (SUBREG_REG (op)); - offset = i * UNITS_PER_WORD + SUBREG_BYTE (op); - /* The SUBREG_BYTE represents offset, as if the value were stored in - memory, except for a paradoxical subreg where we define - SUBREG_BYTE to be 0; undo this exception as in - simplify_subreg. */ - if (SUBREG_BYTE (op) == 0 - && GET_MODE_SIZE (innermostmode) < GET_MODE_SIZE (innermode)) - { - int difference = (GET_MODE_SIZE (innermostmode) - GET_MODE_SIZE (innermode)); - if (WORDS_BIG_ENDIAN) - offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD; - if (BYTES_BIG_ENDIAN) - offset += difference % UNITS_PER_WORD; - } - if (offset >= GET_MODE_SIZE (innermostmode) - || offset <= -GET_MODE_SIZE (word_mode)) - return true; - return false; + machine_mode innermostmode = GET_MODE (SUBREG_REG (op)); + HOST_WIDE_INT offset = i * UNITS_PER_WORD + subreg_memory_offset (op); + return (offset >= GET_MODE_SIZE (innermostmode) + || offset <= -UNITS_PER_WORD); } /* A subroutine of emit_move_insn_1. Generate a move from Y into X. |