diff options
author | vmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-03-28 22:14:36 +0000 |
---|---|---|
committer | vmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-03-28 22:14:36 +0000 |
commit | 28f7a2af1cd69fbd585093981ef571de5aa67df1 (patch) | |
tree | fdee9bbb1c36405dbb87776539318c3b64c8c6df /gcc/lra-constraints.c | |
parent | 6e70f6fbe70fe7ec5fcd0fd680dd299276d1a9e0 (diff) | |
download | gcc-28f7a2af1cd69fbd585093981ef571de5aa67df1.tar.gz |
2014-03-28 Vladimir Makarov <vmakarov@redhat.com>
PR target/60697
* lra-constraints.c (index_part_to_reg): New.
(process_address): Use it.
2014-03-28 Vladimir Makarov <vmakarov@redhat.com>
PR target/60697
* gcc.target/aarch64/pr60697.c: New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@208926 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/lra-constraints.c')
-rw-r--r-- | gcc/lra-constraints.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index ba4d489e9e5..cfc3d7eaaee 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -2631,6 +2631,20 @@ base_plus_disp_to_reg (struct address_info *ad) return new_reg; } +/* Make reload of index part of address AD. Return the new + pseudo. */ +static rtx +index_part_to_reg (struct address_info *ad) +{ + rtx new_reg; + + new_reg = lra_create_new_reg (GET_MODE (*ad->index), NULL_RTX, + INDEX_REG_CLASS, "index term"); + expand_mult (GET_MODE (*ad->index), *ad->index_term, + GEN_INT (get_index_scale (ad)), new_reg, 1); + return new_reg; +} + /* Return true if we can add a displacement to address AD, even if that makes the address invalid. The fix-up code requires any new address to be the sum of the BASE_TERM, INDEX and DISP_TERM fields. */ @@ -2935,7 +2949,7 @@ process_address (int nop, rtx *before, rtx *after) emit_insn (insns); *ad.inner = new_reg; } - else + else if (ad.disp_term != NULL) { /* base + scale * index + disp => new base + scale * index, case (1) above. */ @@ -2943,6 +2957,18 @@ process_address (int nop, rtx *before, rtx *after) *ad.inner = simplify_gen_binary (PLUS, GET_MODE (new_reg), new_reg, *ad.index); } + else + { + /* base + scale * index => base + new_reg, + case (1) above. + Index part of address may become invalid. For example, we + changed pseudo on the equivalent memory and a subreg of the + pseudo onto the memory of different mode for which the scale is + prohibitted. */ + new_reg = index_part_to_reg (&ad); + *ad.inner = simplify_gen_binary (PLUS, GET_MODE (new_reg), + *ad.base_term, new_reg); + } *before = get_insns (); end_sequence (); return true; |