aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2018-01-03 21:42:32 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2018-01-03 21:42:32 +0000
commit79c3f1b3c7e8af1ce1b634326fafe772c4106484 (patch)
tree099d90cf665f2b0f26804d0777367f1ab0feabec /gcc/expr.c
parentbb94ec7613a4fd30c278b236eb8783d985a1b6ee (diff)
downloadgcc-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.c19
1 files changed, 11 insertions, 8 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index 5c1a111..8317d29 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -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)
{