Commit 610c45fc by Richard Sandiford Committed by Richard Sandiford

Make more use of subreg_lowpart_offset

This patch uses subreg_lowpart_offset in places that open-coded
the calculation.  It also uses it in regcprop.c to test whether,
after a mode change, the first register in a multi-register group
is still the right one.

2017-10-13  Richard Sandiford  <richard.sandiford@linaro.org>
	    Alan Hayward  <alan.hayward@arm.com>
	    David Sherwood  <david.sherwood@arm.com>

gcc/
	* calls.c (expand_call): Use subreg_lowpart_offset.
	* cse.c (cse_insn): Likewise.
	* regcprop.c (copy_value): Likewise.
	(copyprop_hardreg_forward_1): Likewise.

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>

From-SVN: r253713
parent 5752d1f7
2017-10-13 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
* calls.c (expand_call): Use subreg_lowpart_offset.
* cse.c (cse_insn): Likewise.
* regcprop.c (copy_value): Likewise.
(copyprop_hardreg_forward_1): Likewise.
2017-10-13 Jakub Jelinek <jakub@redhat.com>
PR target/82524
......@@ -4117,7 +4117,6 @@ expand_call (tree exp, rtx target, int ignore)
{
tree type = rettype;
int unsignedp = TYPE_UNSIGNED (type);
int offset = 0;
machine_mode pmode;
/* Ensure we promote as expected, and get the new unsignedness. */
......@@ -4125,18 +4124,8 @@ expand_call (tree exp, rtx target, int ignore)
funtype, 1);
gcc_assert (GET_MODE (target) == pmode);
if ((WORDS_BIG_ENDIAN || BYTES_BIG_ENDIAN)
&& (GET_MODE_SIZE (GET_MODE (target))
> GET_MODE_SIZE (TYPE_MODE (type))))
{
offset = GET_MODE_SIZE (GET_MODE (target))
- GET_MODE_SIZE (TYPE_MODE (type));
if (! BYTES_BIG_ENDIAN)
offset = (offset / UNITS_PER_WORD) * UNITS_PER_WORD;
else if (! WORDS_BIG_ENDIAN)
offset %= UNITS_PER_WORD;
}
unsigned int offset = subreg_lowpart_offset (TYPE_MODE (type),
GET_MODE (target));
target = gen_rtx_SUBREG (TYPE_MODE (type), target, offset);
SUBREG_PROMOTED_VAR_P (target) = 1;
SUBREG_PROMOTED_SET (target, unsignedp);
......
......@@ -5977,7 +5977,6 @@ cse_insn (rtx_insn *insn)
rtx new_src = 0;
unsigned src_hash;
struct table_elt *src_elt;
int byte = 0;
/* Ignore invalid entries. */
if (!REG_P (elt->exp)
......@@ -5990,13 +5989,8 @@ cse_insn (rtx_insn *insn)
new_src = elt->exp;
else
{
/* Calculate big endian correction for the SUBREG_BYTE.
We have already checked that M1 (GET_MODE (dest))
is not narrower than M2 (new_mode). */
if (BYTES_BIG_ENDIAN)
byte = (GET_MODE_SIZE (GET_MODE (dest))
- GET_MODE_SIZE (new_mode));
unsigned int byte
= subreg_lowpart_offset (new_mode, GET_MODE (dest));
new_src = simplify_gen_subreg (new_mode, elt->exp,
GET_MODE (dest), byte);
}
......
......@@ -345,8 +345,7 @@ copy_value (rtx dest, rtx src, struct value_data *vd)
We can't properly represent the latter case in our tables, so don't
record anything then. */
else if (sn < hard_regno_nregs (sr, vd->e[sr].mode)
&& (GET_MODE_SIZE (vd->e[sr].mode) > UNITS_PER_WORD
? WORDS_BIG_ENDIAN : BYTES_BIG_ENDIAN))
&& subreg_lowpart_offset (GET_MODE (dest), vd->e[sr].mode) != 0)
return;
/* If SRC had been assigned a mode narrower than the copy, we can't
......@@ -871,8 +870,7 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd)
/* And likewise, if we are narrowing on big endian the transformation
is also invalid. */
if (REG_NREGS (src) < hard_regno_nregs (regno, vd->e[regno].mode)
&& (GET_MODE_SIZE (vd->e[regno].mode) > UNITS_PER_WORD
? WORDS_BIG_ENDIAN : BYTES_BIG_ENDIAN))
&& subreg_lowpart_offset (mode, vd->e[regno].mode) != 0)
goto no_move_special_case;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment