diff options
author | Richard Sandiford <richard.sandiford@linaro.org> | 2018-01-03 21:42:32 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2018-01-03 21:42:32 +0000 |
commit | 79c3f1b3c7e8af1ce1b634326fafe772c4106484 (patch) | |
tree | 099d90cf665f2b0f26804d0777367f1ab0feabec /gcc/expr.c | |
parent | bb94ec7613a4fd30c278b236eb8783d985a1b6ee (diff) | |
download | gcc-79c3f1b3c7e8af1ce1b634326fafe772c4106484.zip gcc-79c3f1b3c7e8af1ce1b634326fafe772c4106484.tar.gz gcc-79c3f1b3c7e8af1ce1b634326fafe772c4106484.tar.bz2 |
poly_int: expand_assignment
This patch makes the CONCAT handing in expand_assignment cope with
polynomial mode sizes. The mode of the CONCAT must be complex,
so we can base the tests on the sizes of the real and imaginary
components.
2018-01-03 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
gcc/
* expr.c (expand_assignment): Cope with polynomial mode sizes
when assigning to a CONCAT.
Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r256199
Diffstat (limited to 'gcc/expr.c')
-rw-r--r-- | gcc/expr.c | 19 |
1 files changed, 11 insertions, 8 deletions
@@ -5131,25 +5131,28 @@ expand_assignment (tree to, tree from, bool nontemporal) /* Handle expand_expr of a complex value returning a CONCAT. */ else if (GET_CODE (to_rtx) == CONCAT) { - unsigned short mode_bitsize = GET_MODE_BITSIZE (GET_MODE (to_rtx)); + machine_mode to_mode = GET_MODE (to_rtx); + gcc_checking_assert (COMPLEX_MODE_P (to_mode)); + poly_int64 mode_bitsize = GET_MODE_BITSIZE (to_mode); + unsigned short inner_bitsize = GET_MODE_UNIT_BITSIZE (to_mode); if (TYPE_MODE (TREE_TYPE (from)) == GET_MODE (to_rtx) && COMPLEX_MODE_P (GET_MODE (to_rtx)) && known_eq (bitpos, 0) && known_eq (bitsize, mode_bitsize)) result = store_expr (from, to_rtx, false, nontemporal, reversep); - else if (known_eq (bitsize, mode_bitsize / 2) + else if (known_eq (bitsize, inner_bitsize) && (known_eq (bitpos, 0) - || known_eq (bitpos, mode_bitsize / 2))) + || known_eq (bitpos, inner_bitsize))) result = store_expr (from, XEXP (to_rtx, maybe_ne (bitpos, 0)), false, nontemporal, reversep); - else if (known_le (bitpos + bitsize, mode_bitsize / 2)) + else if (known_le (bitpos + bitsize, inner_bitsize)) result = store_field (XEXP (to_rtx, 0), bitsize, bitpos, bitregion_start, bitregion_end, mode1, from, get_alias_set (to), nontemporal, reversep); - else if (known_ge (bitpos, mode_bitsize / 2)) + else if (known_ge (bitpos, inner_bitsize)) result = store_field (XEXP (to_rtx, 1), bitsize, - bitpos - mode_bitsize / 2, + bitpos - inner_bitsize, bitregion_start, bitregion_end, mode1, from, get_alias_set (to), nontemporal, reversep); @@ -5158,7 +5161,7 @@ expand_assignment (tree to, tree from, bool nontemporal) result = expand_normal (from); if (GET_CODE (result) == CONCAT) { - machine_mode to_mode = GET_MODE_INNER (GET_MODE (to_rtx)); + to_mode = GET_MODE_INNER (to_mode); machine_mode from_mode = GET_MODE_INNER (GET_MODE (result)); rtx from_real = simplify_gen_subreg (to_mode, XEXP (result, 0), @@ -5174,7 +5177,7 @@ expand_assignment (tree to, tree from, bool nontemporal) else { rtx from_rtx - = simplify_gen_subreg (GET_MODE (to_rtx), result, + = simplify_gen_subreg (to_mode, result, TYPE_MODE (TREE_TYPE (from)), 0); if (from_rtx) { |