From: "Ulrich Weigand" <uweigand@de.ibm.com>
To: julian@codesourcery.com (Julian Brown)
Cc: gcc-patches@gcc.gnu.org, paul@codesourcery.com, rearnsha@arm.com,
ramana.radhakrishnan@linaro.org (Ramana Radhakrishnan)
Subject: Re: [PATCH, ARM] Unaligned accesses for packed structures [1/2]
Date: Mon, 04 Jul 2011 11:44:00 -0000 [thread overview]
Message-ID: <201107041143.p64BhV9P016874@d06av02.portsmouth.uk.ibm.com> (raw)
In-Reply-To: <20110506133414.14dc027c@rex.config> from "Julian Brown" at May 06, 2011 01:34:14 PM
Julian Brown wrote:
> The most awkward change in the patch is to generic code (expmed.c,
> {store,extract}_bit_field_1): in big-endian mode, the existing behaviour
> (when inserting/extracting a bitfield to a memory location) is
> definitely bogus: "unit" is set to BITS_PER_UNIT for memory locations,
> and if bitsize (the size of the field to insert/extract) is greater than
> BITS_PER_UNIT (which isn't unusual at all), xbitpos becomes negative.
> That can't possibly be intentional; I can only assume that this code
> path is not exercised for machines which have memory alternatives for
> bitfield insert/extract, and BITS_BIG_ENDIAN of 0 in BYTES_BIG_ENDIAN
> mode.
[snip]
> @@ -648,7 +648,7 @@ store_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
> /* On big-endian machines, we count bits from the most significant.
> If the bit field insn does not, we must invert. */
>
> - if (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
> + if (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN && !MEM_P (xop0))
> xbitpos = unit - bitsize - xbitpos;
I agree that the current code cannot possibly be correct. However, just
disabling the BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN renumbering *completely*
seems wrong to me as well.
According to the docs, the meaning bit position passed to the extv/insv
expanders is determined by BITS_BIG_ENDIAN, both in the cases of register
and memory operands. Therefore, if BITS_BIG_ENDIAN differs from
BYTES_BIG_ENDIAN, we should need a correction for memory operands as
well. However, this correction needs to be relative to the size of
the access (i.e. the operand to the extv/insn), not just BITS_PER_UNIT.
From looking at the sources, the simplest way to implement that might
be to swap the order of the two corrections, that is, change this:
/* On big-endian machines, we count bits from the most significant.
If the bit field insn does not, we must invert. */
if (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
xbitpos = unit - bitsize - xbitpos;
/* We have been counting XBITPOS within UNIT.
Count instead within the size of the register. */
if (BITS_BIG_ENDIAN && !MEM_P (xop0))
xbitpos += GET_MODE_BITSIZE (op_mode) - unit;
unit = GET_MODE_BITSIZE (op_mode);
to look instead like:
/* We have been counting XBITPOS within UNIT.
Count instead within the size of the register. */
if (BYTES_BIG_ENDIAN && !MEM_P (xop0))
xbitpos += GET_MODE_BITSIZE (op_mode) - unit;
unit = GET_MODE_BITSIZE (op_mode);
/* On big-endian machines, we count bits from the most significant.
If the bit field insn does not, we must invert. */
if (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
xbitpos = unit - bitsize - xbitpos;
(Note that the condition in the first if must then check BYTES_BIG_ENDIAN
instead of BITS_BIG_ENDIAN.) This change results in unchanged behaviour
for register operands in all cases, and memory operands if BITS_BIG_ENDIAN
== BYTES_BIG_ENDIAN. For the problematic case of memory operands with
BITS_BIG_ENDIAN != BYTES_BIG ENDIAN it should result in the appropriate
correction.
Note that with that change, the new code your patch introduces to the
ARM back-end will also need to change. You currently handle bitpos
like this:
base_addr = adjust_address (operands[1], HImode,
bitpos / BITS_PER_UNIT);
This implicitly assumes that bitpos counts according to BYTES_BIG_ENDIAN,
not BITS_BIG_ENDIAN -- which exactly cancels out the common code behaviour
introduced by your patch ...
Thoughts? Am I overlooking something here?
Bye,
Ulrich
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com
next prev parent reply other threads:[~2011-07-04 11:44 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-05-06 12:45 Julian Brown
2011-05-06 13:07 ` Richard Earnshaw
2011-05-09 17:50 ` Julian Brown
2011-05-10 14:03 ` Julian Brown
2011-05-26 17:06 ` Julian Brown
2011-07-04 11:44 ` Ulrich Weigand [this message]
2011-08-25 16:29 ` Julian Brown
2011-08-25 18:19 ` Julian Brown
2011-08-25 22:18 ` Ramana Radhakrishnan
2011-08-25 22:23 ` Joseph S. Myers
2011-08-26 17:37 ` Julian Brown
2011-09-08 17:35 ` Richard Earnshaw
2011-09-01 14:46 ` Ulrich Weigand
2011-09-22 6:47 ` Ye Joey
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=201107041143.p64BhV9P016874@d06av02.portsmouth.uk.ibm.com \
--to=uweigand@de.ibm.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=julian@codesourcery.com \
--cc=paul@codesourcery.com \
--cc=ramana.radhakrishnan@linaro.org \
--cc=rearnsha@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).