On Thu, Aug 17, 2017 at 04:27:12PM +0200, Michael Matz wrote:
> Hi,
>
> On Mon, 14 Aug 2017, Alan Modra wrote:
>
> > I've opened https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81845 to track
> > the lack of documentation.
>
> You mean like in this paragraph discussing memory clobbers and uses in
> extended asms that we have since 2004? :
The paragraph you show below (from gcc-4 sources) disappeared with git
commit 3aabc45f2. We currently have this:
------
Flushing registers to memory has performance implications and may be an issue
for time-sensitive code. You can use a trick to avoid this if the size of
the memory being accessed is known at compile time. For example, if accessing
ten bytes of a string, use a memory input like:
@code{@{"m"( (@{ struct @{ char x[10]; @} *p = (void *)ptr ; *p; @}) )@}}.
------
So, no example even of the simplest "m" (*y) type memory input. This
lack was part of the reason I submitted
https://gcc.gnu.org/ml/gcc-patches/2017-03/msg01562.html
which died in the review process, mostly due to the example being
rather large, and partly I fear, due to not being x86. I didn't push
the patch for a number of reasons. Then later realized that the
constraints I was using for arrays, while they work for OpenBLAS, were
not strict enough. "m" (*y) for an array y only makes the asm depend
on y[0].
I have a couple of documentation patches prepared, and have been
poking around in the source to verify that what I'm proposing for
indeterminate length arrays, "m" (*(const T (*)[]) ptr) and
"=m" (*(T (*)[]) ptr) is reasonable. One obvious problem is that the
cast expression isn't a proper lvalue, but I'm encouraged to find
comments in the source complaining that such things need to be
tolerated in asm. :)
>
> ----------------
> If your assembler instructions access memory in an unpredictable
> fashion, add `memory' to the list of clobbered registers. This will
> cause GCC to not keep memory values cached in registers across the
> assembler instruction and not optimize stores or loads to that memory.
> You will also want to add the `volatile' keyword if the memory affected
> is not listed in the inputs or outputs of the `asm', as the `memory'
> clobber does not count as a side-effect of the `asm'. If you know how
> large the accessed memory is, you can add it as input or output but if
> this is not known, you should add `memory'. As an example, if you
> access ten bytes of a string, you can use a memory input like:
>
> {"m"( ({ struct { char x[10]; } *p = (void *)ptr ; *p; }) )}.
>
> Note that in the following example the memory input is necessary,
> otherwise GCC might optimize the store to `x' away:
> int foo ()
> {
> int x = 42;
> int *y = &x;
> int result;
> asm ("magic stuff accessing an 'int' pointed to by '%1'"
> "=&d" (r) : "a" (y), "m" (*y));
> return result;
> }
> ----------------
>
>
> Ciao,
> Michael.
--
Alan Modra
Australia Development Lab, IBM